首页 > 其他分享 >k8s系列之五通过Service访问Pod

k8s系列之五通过Service访问Pod

时间:2024-12-12 10:53:35浏览次数:4  
标签:comment httpd k8s Service -- svc 之五 Pod KUBE

参考:https://blog.csdn.net/u011067966/article/details/135885967

 

1.0变更

因本地原因,k8s系列之二集群环境搭建以及插件安装 中的虚拟机更换为以下3个节点,后续文章均在此三个节点上实践:
节点    ip
k8s-master    192.168.200.128
k8s-node1    192.168.200.129
k8s-node2    192.168.200.130

假设Pod中的容器很可能因为各种原因发生故障而死掉。Deployment等Controller会通过动态创建和销毁Pod来保证应用整体的健壮性。换句话说,Pod是脆弱的,但应用是健壮的。

每个Pod都有自己的IP地址。当Controller用新Pod替代发生故障的Pod时,新Pod会分配到新的IP地址。这样就产生了⼀个问题:如果⼀组Pod对外提供服务(比如HTTP),它们的IP很有可能发⽣变化,那么客户端如何找到并访问这个服务呢?Kubernetes给出的解决方案是Service。
1.1 Service是什么

由于Pod的动态性,Service解决了一个重要问题:如果一组Pod(称为“后端”)为其他Pod(称为“前端”)提供服务,前端如何找到并连接到后端的IP地址。Kubernetes中的Service为此提供了解决方案,通过提供稳定的虚拟IP和DNS,使服务发现变得简单而可靠。
1.2 Service的几种类型

(1)ClusterIP
ClusterIP 服务是 Kubernetes 的默认服务。它给你一个集群内的服务,集群内的其它应用都可以访问该服务,但是集群外部无法访问它。
(2)NodePort
除了只在内部访问的服务,我们总有很多是需要暴露出来公开访问的服务吧。在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过:NodePort来访问这些服务。
(3)LoadBalancer
LoadBalancer 服务是暴露服务到 internet 的标准方式,它借助Cloud Provider创建一个外部的负载均衡器,并将请求转发到:NodePort(向节点导流)。
1.3 ClusterIP

先创建Deployment。
vi httpd.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd
spec:
  replicas: 3
  selector:  # 添加这一行,定义标签选择器
    matchLabels:
      run: httpd
  template:
    metadata:
      labels:
        run: httpd
    spec:
      containers:
      - name: httpd
        image: httpd
        ports:
        - containerPort: 80

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

我们启动了三个Pod,运行httpd镜像,label是run: httpd,Service将会用这个label来挑选Pod。

kubectl get pod -o wide

    1

Pod分配了各自的IP,这些IP只能被KubernetesCluster中的容器和节点访问,如图所示。

[root@k8s-master ~]# kubectl get pod -o wide
NAME                                READY   STATUS      RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
httpd-ff8d77b9b-dpp79               1/1     Running     1          43h   10.244.2.104   k8s-node2   <none>           <none>
httpd-ff8d77b9b-n5w6x               1/1     Running     1          43h   10.244.2.103   k8s-node2   <none>           <none>
httpd-ff8d77b9b-t6jhg               1/1     Running     1          43h   10.244.2.105   

    1
    2
    3
    4
    5

[root@k8s-master ~]# curl 10.244.2.103
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 10.244.2.104
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 10.244.2.105
<html><body><h1>It works!</h1></body></html>

    1
    2
    3
    4
    5
    6
    7

接下来创建Service,其配置文件如下。
vi httpdservice.yaml

apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
spec:
  selector:
    run: httpd
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 80

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

执⾏kubectl apply创建Service httpd-svc,查看service

kubectl get service

    1

[root@k8s-master ~]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
httpd-svc    ClusterIP   10.1.216.8   <none>        8080/TCP   43h
kubernetes   ClusterIP   10.1.0.1     <none>        443/TCP    10d

    1
    2
    3
    4

httpd-svc分配到⼀个CLUSTER-IP 10.1.216.8。可以通过该IP访问后端的httpd Pod,如图。

[root@k8s-master ~]# curl 10.1.216.8:8080
<html><body><h1>It works!</h1></body></html>

    1
    2

通过kubectl describe可以查看httpd-svc与Pod的对应关系,如图

[root@k8s-master ~]# kubectl describe service httpd-svc
Name:              httpd-svc
Namespace:         default
Labels:            <none>
Annotations:       Selector:  run=httpd
Type:              ClusterIP
IP:                10.1.216.8
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.103:80,10.244.2.104:80,10.244.2.105:80
Session Affinity:  None
Events:            <none>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

Endpoints罗列了三个Pod的IP和端口。我们知道Pod的IP是在容器中配置的,那么Service的Cluster IP又是配置在哪⾥的呢?CLUSTER-IP又是如何映射到Pod IP的呢?
答案是iptables。
1.4 Cluster IP底层实现

ClusterIP是⼀个虚拟IP,是由Kubernetes节点上的iptables规则管理的。可以通过iptables-save命令打印出当前节点的iptables规则,因为输出较多,这里只截取与httpd-svcClusterIP10.1.216.8相关的信息,如下。

-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.1.216.8/32 -p tcp -m comment --comment "default/httpd-svc: cluster IP" -m tcp --dport 808       0 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.1.216.8/32 -p tcp -m comment --comment "default/httpd-svc: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-RL3JAE4GN7VOGDGP

    1
    2
    3

这两条规则的含义是:
(1)如果Cluster内的Pod(源地址来⾃10.244.0.0/16)要访问
httpd-svc,则允许。
(2)其他源地址访问httpd-svc,跳转到规则KUBE-SVC-
RL3JAE4GN7VOGDGP。KUBE-SVC-RL3JAE4GN7VOGDGP规则如下。

-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.33333333349 -j KU       BE-SEP-EQHMOIHNIUPMH73P
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.50000000000 -j KU       BE-SEP-7VYTM2IXTFTHGXZQ
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -j KUBE-SEP-6OZMKNJKUPLE2HZF

    1
    2
    3
    4

(1)1/3的概率跳转到规则KUBE-SEP-EQHMOIHNIUPMH73P。
(2)1/3的概率(剩下2/3的⼀半)跳转到规则KUBE-SEP-7VYTM2IXTFTHGXZQ。
(3)1/3的概率跳转到规则KUBE-SEP-6OZMKNJKUPLE2HZF。

-A KUBE-SEP-EQHMOIHNIUPMH73P -s 10.244.2.106/32 -m comment --comment "default/httpd-svc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-EQHMOIHNIUPMH73P -p tcp -m comment --comment "default/httpd-svc:" -m tcp -j DNAT --to-destination 10.244.2.106:80

-A KUBE-SEP-7VYTM2IXTFTHGXZQ -s 10.244.2.107/32 -m comment --comment "default/httpd-svc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-7VYTM2IXTFTHGXZQ -p tcp -m comment --comment "default/httpd-svc:" -m tcp -j DNAT --to-destination 10.244.2.107:80

-A KUBE-SEP-6OZMKNJKUPLE2HZF -s 10.244.2.108/32 -m comment --comment "default/httpd-svc:" -j KUBE-MARK-MASQ
-A KUBE-SEP-6OZMKNJKUPLE2HZF -p tcp -m comment --comment "default/httpd-svc:" -m tcp -j DNAT --to-destination 10.244.2.108:80

    1
    2
    3
    4
    5
    6
    7
    8
    9

可以看到是将请求分别转发到后端的三个Pod。
通过上面的分析,我们得到结论:iptables将访问Service的流量转发到后端Pod,而且使用类似轮询的负载均衡策略。
1.5 DNS访问Service

kubeadm部署时会默认安装kube-dns组件。

[root@k8s-master ~]#  kubectl get deployment --namespace=kube-system
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
coredns          2/2     2            2           12d
metrics-server   1/1     1            1           12d

    1
    2
    3
    4

kube-dns是⼀个DNS服务器。每当有新的Service被创建,kube-dns会添加该Service的DNS记录。Cluster中的Pod可以通过<SERVICE_NAME>.<NAMESPACE_NAME>访问Service。比如可以用httpd-svc.default访问Servicehttpd-svc。

[root@k8s-master ~]# kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # curl httpd-svc.default:8080
/bin/sh: curl: not found
/ # wget httpd-svc.default:8080
Connecting to httpd-svc.default:8080 (10.1.216.8:8080)
saving to 'index.html'
index.html           100% |******************************************************************************************|    45  0:00:00 ETA
'index.html' saved

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

如果要访问其他namespace中的Service,就必须带上namesapce了。在kube-public中部署Service httpd2-svc。
vi httpd2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd2
  namespace: kube-public
spec:
  replicas: 1
  selector:
    matchLabels:
      run: httpd2
  template:
    metadata:
      labels:
        run: httpd2
    spec:
      containers:
      - name: httpd2
        image: httpd
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: httpd2-svc
  namespace: kube-public
spec:
  selector:
    run: httpd2
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

通过namespace:kube-public指定资源所属的namespace。多个资源可以在⼀个YAML⽂件中定义,⽤“—”分割。执⾏kubectlapply创建资源。

[root@k8s-master ~]#  kubectl apply -f httpd2.yaml
deployment.apps/httpd2 created
service/httpd2-svc unchanged
[root@k8s-master ~]# kubectl get service --namespace=kube-public
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
httpd2-svc   ClusterIP   10.1.19.55   <none>        8080/TCP   9m15s
[root@k8s-master ~]# kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget httpd2-svc.kube-public:8080
Connecting to httpd2-svc.kube-public:8080 (10.1.19.55:8080)
saving to 'index.html'
index.html           100% |******************************************************************************************|    45  0:00:00 ETA
'index.html' saved

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

1.5 NodePort

Service通过Cluster节点的静态端口对外提供服务。Cluster外部可以通过:访问Service。
下面我们来实践NodePort,Service httpd-svc的配置文件修改。
vi httpdservice.yaml

apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
spec:
  type: NodePort
  selector:
    run: httpd
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 80

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

添加type: NodePort,重新创建httpd-svc

[root@k8s-master ~]# vi httpdservice.yaml
[root@k8s-master ~]#  kubectl apply -f httpdservice.yaml
service/httpd-svc configured
[root@k8s-master ~]# kubectl get service httpd-svc
NAME        TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
httpd-svc   NodePort   10.1.216.8   <none>        8080:30560/TCP   2d23h

    1
    2
    3
    4
    5
    6

Kubernetes依然会为httpd-svc分配⼀个ClusterIP,不同的是:
(1)EXTERNAL-IP为nodes,表示可通过Cluster每个节点自身的IP访问Service。
(2)PORT(S)为8080:30560。8080是ClusterIP监听的端口,30560则是节点上监听的端口。Kubernetes会从30000〜32767中分配⼀个可用的端口,每个节点都会监听此端⼝并将请求转发给Service。

测试NodePort是否正常工作,通过三个节点IP+30560端口都能够访问httpd-svc。:

[root@k8s-master ~]# curl 192.168.200.128:30560
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.129:30560
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.130:30560
<html><body><h1>It works!</h1></body></html>

    1
    2
    3
    4
    5
    6

Kubernetes是如何将:映射到Pod的呢?执行iptables-save
与ClusterIP⼀样,也是借助了iptables。与ClusterIP相比,每个节点的iptables中都增加了下面两条规则。

-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 30560 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/httpd-svc:" -m tcp --dport 30560 -j KUBE-SVC-RL3JAE4GN7VOGDGP

    1
    2

规则的含义是:访问当前节点32312端口的请求会应用规则KUBE-
SVC-RL3JAE4GN7VOGDGP,内容如下

-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-EQHMOIHNIUPMH73P
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-7VYTM2IXTFTHGXZQ
-A KUBE-SVC-RL3JAE4GN7VOGDGP -m comment --comment "default/httpd-svc:" -j KUBE-SEP-6OZMKNJKUPLE2HZF

    1
    2
    3

其作用就是负载均衡到每⼀个Pod。

NodePort默认的是随机选择,不过我们可以用nodePort指定某个特定端口。
vi httpdservice.yaml

apiVersion: v1
kind: Service
metadata:
  name: httpd-svc
spec:
  type: NodePort
  selector:
    run: httpd
  ports:
    - protocol: TCP
      nodePort: 31000
      port: 8080
      targetPort: 80

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

现在配置文件中就有三个Port了:

    nodePort是节点上监听的端口。
    port是ClusterIP上监听的端口。
    targetPort是Pod监听的端口。

[root@k8s-master ~]# vi httpdservice.yaml
[root@k8s-master ~]#  kubectl apply -f httpdservice.yaml
service/httpd-svc configured
[root@k8s-master ~]# curl 192.168.200.130:31000
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.128:31000
<html><body><h1>It works!</h1></body></html>
[root@k8s-master ~]# curl 192.168.200.129:31000
<html><body><h1>It works!</h1></body></html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

最终,Node和ClusterIP在各自端口上接收到的请求都会通过 iptables转发到Pod的targetPort。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/u011067966/article/details/135885967

标签:comment,httpd,k8s,Service,--,svc,之五,Pod,KUBE
From: https://www.cnblogs.com/gaoyanbing/p/18601952

相关文章

  • ServiceMesh 5:异常重试和超时保护提升服务可用性
    ★ServiceMesh系列1背景在复杂的互联网场景中,不可避免的会出现请求失败或者超时的情况。从程序的的响应结果来看,一般是Response返回5xx状态的错误;从用户的角度去看,一般是请求结果不符合预期,即操作失败(如转账失败、下单失败、信息获取不到等)。偶发的不可避免的5xx请求错误,产......
  • ntp-service unicast-server命令的含义
    ntp-serviceunicast-server 是网络时间协议(NTP)配置中的一项,用于在设备(如路由器或交换机)上设置NTP服务,以单播模式与特定时间服务器进行同步。以下是相关概念和配置说明:1.什么是单播模式(UnicastMode)单播模式是NTP的一种通信方式,设备直接向指定的NTP服务器发送时......
  • 转载:【AI系统】谷歌 TPUv3 POD 形态
    TPUv3vs.TPUv2TPUv3实际上就是TPUv2的增强版。TPUv3相比TPUv2有约1.35倍的时钟频率、ICI贷款和内存带宽,两杯MXU数量,峰值性能提高2.7倍。在同样使用除了显眼的蓝色外,相比于TPUv2,TPUv3在只增大10%体积的情况下增加了MXU的数量,从2个翻倍到了4......
  • 转载:【AI系统】谷歌 TPUv3 POD 形态
    TPUv3vs.TPUv2TPUv3实际上就是TPUv2的增强版。TPUv3相比TPUv2有约1.35倍的时钟频率、ICI贷款和内存带宽,两杯MXU数量,峰值性能提高2.7倍。在同样使用除了显眼的蓝色外,相比于TPUv2,TPUv3在只增大10%体积的情况下增加了MXU的数量,从2个翻倍到了4......
  • JAVA中ScheduledExecutorService的使用方法
    ScheduledExecutorService简介ScheduledExecutorService是Java中的一个接口,它是ExecutorService的子接口。它主要用于在给定的延迟之后或周期性地执行任务。这个接口提供了一种方便的方式来处理异步任务的调度,相比于传统的Timer和TimerTask,它具有更好的灵活性和可靠性,特别是......
  • 调用WebService异常:提供的 URI 方案“https”无效,应为“http”。 (Parameter 'via')
    解决办法:varbinding=newBasicHttpBinding();binding.Security.Mode=BasicHttpSecurityMode.Transport;<bindings><customBinding><bindingname="ZWS_CUST"><mtomMessageEncodingmes......
  • New-Bom-BomService
    好的,我们将根据之前的内容,专注于实现应用层的CQRS(命令查询职责分离)模式。CQRS是一种架构模式,它将读取操作与写入操作分离,通常使用不同的模型来处理命令和查询。我们将使用MediatR库来简化CQRS的实现,并确保每个部分都清晰明了。安装MediatR首先,在MyCc.Application和M......
  • 配置ingress将service中的端口暴露出去
    service是管理pod的暴露的,但是每个service都暴露一个端口到外部并不是很合适。使用ingress将不同的service暴露的端口通过子url的方式做反向代理,使用7层代理方式暴露给外部。配置ingress-nginx需要先按照前面讲解的安装方式安装一下,然后就可以修改helm的values.yaml配置文......
  • 云端全托管搜索引擎Elasticsearch Service产品介绍
    ElasticsearchService(ES)是云端全托管海量数据检索分析服务,拥有高性能内核,集成X-Pack。ES支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的Serverless模式。使用ES您可以高效构建信息检索、日志分析、运维监控等服务,它独特......
  • Abp-VNext用户权限管理系列文章09---集成webservice
    1、dBridge.WmsService.Host、Bridge.Wms.HttpApi中引用soapcore 2、WmsServiceHostModule中注入服务ConfigureServices方法中//注入WebServicecontext.Services.AddSoapCore(); OnApplicationInitialization方法中app.UseSoapEndpoint<IOrderWebService>("/Orde......