11、Kubernetes核心技术 - Service

2023-09-19 17:24:53

目录

一、概述

二、Endpoint

三、Service资源清单

四、Service 类型

4.1、ClusterIP

4.2、NodePort

4.3、LoadBalancer

4.4、ExternalName

五、Service使用

5.1、ClusterIP

5.1.1、定义Pod资源清单

5.1.2、创建Pod

5.1.3、定义Service资源清单

5.1.4、创建Service

5.2、NodePort

5.2.1、集群内通过ClusterIP+虚端口访问

5.2.2、集群外通过NodeIP+nodePort端口访问

5.2.3、集群内通过Pod IP + 虚端口访问

5.3、ExternalName

六、Service代理模式

6.1、userspace 代理模式

6.2、iptables 代理模式

6.3、IPVS 代理模式

6.3.1、加载ipvs相关内核模块 

6.3.2、编辑配置文件

6.3.3、删除原有的kube-proxy代理 

6.3.4、查看IPVS

七、HeadLiness services

7.1、创建Pod

7.2、创建Service

7.3、进入容器,查看服务域名 


一、概述

在k8s中,Pod是应用程序的载体,我们可以通过Pod的IP地址来访问应用程序,但是当Pod宕机后重建后,其IP地址等状态信息可能会变动,也就是说Pod的IP地址不是固定的,这也就意味着不方便直接采用Pod的IP地址对服务进行访问。

为了解决这个问题,k8s提供了Service资源,Service会对提供同一个服务的多个Pod进行聚合,并且提供一个统一的入口地址,通过访问Service的入口地址就能访问到后面的Pod服务 ,并且将请求负载分发到后端的各个容器应用上 。

Service引入主要是解决Pod的动态变化,提供统一的访问入口

  • 1、防止Pod失联,准备找到提供同一服务的Pod(服务发现)
  • 2、定义一组Pod的访问策略(负载均衡)

Service通常是通过Label Selector访问一组Pod,如下图:

其实 Service 只是一个概念,真正起到转发数据的是 kube-proxy 服务进程,kube-proxy 是集群中每个节点上运行的网络代理,每个节点之上都运行一个 kube-proxy 服务进程。当创建 Service 的时候,首先API Server向 etcd 写入 Service 的信息,然后kube-proxy会监听API Server,监听到etcd中 Service 的信息,然后根据Service的信息生成对应的访问规则。

二、Endpoint

Endpoint是kubernetes中的一个资源对象,存储在etcd中,用来记录一个Service对应的所有Pod的访问地址,它是根据Service配置文件中的label selector(标签选择器)生成的。

一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换言之,Service和Pod之间的联系是通过Endpoints实现的。

当我们创建Service的时候,如果Service有指定Label Selector(标签选择器)的话,Endpoints控制器会自动创建一个名称跟Service名称一致的Endpoint对象。可简单理解为,Endpoint是一个中间对象,用来存放Service与Pod的映射关系,在Endpoint中,可以看到,当前能正常提供服务的Pod以及不能正常提供的Pod。

例如:

$ kubectl get pod -o wide --show-labels
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES   LABELS
nginx-7f456874f4-c7224   1/1     Running   0          20m   192.168.1.3   node01         <none>           <none>            app=nginx,pod-template-hash=7f456874f4
nginx-7f456874f4-v8pnz   1/1     Running   0          20m   192.168.0.6   controlplane   <none>           <none>            app=nginx,pod-template-hash=7f456874f4

$ kubectl get svc -o wide              
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   14d   <none>
nginx        ClusterIP   10.109.113.53   <none>        80/TCP    12m   app=nginx

$ kubectl get ep
NAME         ENDPOINTS                       AGE
kubernetes   172.30.1.2:6443                 14d
nginx        192.168.0.6:80,192.168.1.3:80   12m

# 查看endpoint资源清单
$ kubectl get ep nginx -o yaml
apiVersion: v1
kind: Endpoints
metadata:
  annotations:
    endpoints.kubernetes.io/last-change-trigger-time: "2023-01-06T06:33:26Z"
  creationTimestamp: "2023-01-06T06:33:27Z"
  name: nginx		# Endpoint名称,跟service的名称一样
  namespace: default
  resourceVersion: "2212"
  uid: 5c1d6639-c27a-4ab5-8832-64c9d618a209
subsets:
- addresses:		# Ready addresses表示能正常提供服务的Pod, 还有一个NotReadyAddress表示不能提供正常服务的Pod
  - ip: 192.168.0.6			# Pod的IP地址
    nodeName: controlplane		# Pod被调度到的节点
    targetRef:
      kind: Pod
      name: nginx-7f456874f4-v8pnz
      namespace: default
      uid: b248209d-a854-48e8-8162-1abd4e1b498f
  - ip: 192.168.1.3			# Pod的IP地址
    nodeName: node01			# Pod被调度到的节点
    targetRef:
      kind: Pod
      name: nginx-7f456874f4-c7224
      namespace: default
      uid: f45e4aa2-ddfd-48cd-a7d1-5bfb28d0f31f
  ports:
  - port: 80
    protocol: TCP

Service与Endpoints、Pod的关系大体如下:

三、Service资源清单

yaml 格式的 Service 定义文件 :kubectl get svc nginx -o yaml

apiVersion: v1  	 # 版本号
kind: Service  		# 资源类型,固定值Service
metadata: 	# 元数据
  creationTimestamp: "2022-12-29T08:46:28Z"
  labels:			# 自定义标签属性列表
    app: nginx  		#  标签:app=nginx
  name: nginx			# Service名称
  namespace: default			# Service所在的命名空间,默认值为default
  resourceVersion: "2527"
  uid: 1770ab42-bd33-4455-a190-5753e8eac460
spec:	
  clusterIP: 10.102.82.102		# 虚拟服务的IP地址,当spec.type=ClusterIP时,如果不指定,则系统进行自动分配,也可以手工指定。当spec.type=LoadBalancer时,则需要指定
  clusterIPs:
  - 10.102.82.102
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:		# Service需要暴露的端口列表
  - nodePort: 30314				# 当spec.type=NodePort时,指定映射到物理机的端口号
    port: 80			# 服务监听的端口号
    protocol: TCP			# 端口协议,支持TCP和UDP,默认值为TCP
    targetPort: 80		# 需要转发到后端Pod的端口号
  selector:			# label selector配置,将选择具有指定label标签的pod作为管理范围
    app: nginx   	#  选择具有app=nginx的pod进行管理
  sessionAffinity: None		# session亲和性,可选值为ClientIP,表示将同一个源IP地址的客户端访问请求都转发到同一个后端Pod。默认值为空【None】
  type: NodePort		#  Service的类型,指定service的访问方式,默认值为ClusterIP。取值范围:[ClusterIP、NodePort、LoadBalancer]
status:
  loadBalancer: {} 	# 当spec.type=LoadBalancer时,设置外部负载均衡器的地址,用于公有云环境

四、Service 类型

Service在k8s中有以下三种常用类型:

4.1、ClusterIP

只能在集群内部访问,默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP(即VIP)。

4.2、NodePort

在每个主机节点上启用一个端口来暴露服务,可以在集群外部访问,也会分配一个稳定内部集群IP地址。

访问地址:<任意Node节点的IP地址>: NodePort端口

默认NodePort端口范围:30000-32767

4.3、LoadBalancer

与NodePort类似,在每个节点上启用一个端口来暴露服务。除此之外,Kubernetes会请求底层云平台(例如阿里云、腾讯云、AWS等)上的负载均衡器,将每个Node ([NodeIP]:[NodePort])作为后端添加进去,此模式需要外部云环境的支持,适用于公有云。

4.4、ExternalName

ExternalName Service用于引入集群外部的服务,它通过externalName属性指定一个服务的地址,然后在集群内部访问此Service就可以访问到外部的服务了。

五、Service使用

5.1、ClusterIP

5.1.1、定义Pod资源清单

vim clusterip-pod.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
              protocol: TCP

5.1.2、创建Pod

$ kubectl apply -f clusterip-pod.yaml 
deployment.apps/nginx created

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
nginx-7f456874f4-c7224   1/1     Running   0          13s   192.168.1.3   node01         <none>           <none>
nginx-7f456874f4-v8pnz   1/1     Running   0          13s   192.168.0.6   controlplane   <none>           <none>

# 任意节点发起请求
$ curl 192.168.1.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

# 任意节点发起请求
$ curl 192.168.0.6
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

由于pod节点都是nginx默认界面都是一样的,为了方便测试,我们进入Pod修改默认界面:

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
nginx-7f456874f4-c7224   1/1     Running   0          2m39s   192.168.1.3   node01         <none>           <none>
nginx-7f456874f4-v8pnz   1/1     Running   0          2m39s   192.168.0.6   controlplane   <none>           <none>

$ kubectl exec -it nginx-7f456874f4-c7224 /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# echo "hello, this request is from 192.168.1.3" > /usr/share/nginx/html/index.html
# 
# cat /usr/share/nginx/html/index.html
hello, this request is from 192.168.1.3
# exit

$ kubectl exec -it nginx-7f456874f4-v8pnz /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# echo "hello, this request is from 192.168.0.6" > /usr/share/nginx/html/index.html
# cat /usr/share/nginx/html/index.html
hello, this request is from 192.168.0.6
# exit

# 发起请求
$ curl 192.168.1.3
hello, this request is from 192.168.1.3
$ curl 192.168.0.6
hello, this request is from 192.168.0.6

5.1.3、定义Service资源清单

vim clusterip-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  type: ClusterIP
  # clusterIP: 10.109.113.53   # service IP地址 如果不写默认会生成一个
  ports:
    - port: 80		# service端口
      targetPort: 80		# 目标pod端口

5.1.4、创建Service

$ kubectl apply -f clusterip-svc.yaml 
service/nginx created

$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   14d   <none>
nginx        ClusterIP   10.109.113.53   <none>        80/TCP    15s   app=nginx

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
nginx-7f456874f4-c7224   1/1     Running   0          11m   192.168.1.3   node01         <none>           <none>
nginx-7f456874f4-v8pnz   1/1     Running   0          11m   192.168.0.6   controlplane   <none>           <none>

# 查看svc的详细描述信息,注意Endpoints表示的就是后端真实的Pod服务节点
$ kubectl describe svc nginx
Name:              nginx
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.109.113.53
IPs:               10.109.113.53
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.0.6:80,192.168.1.3:80		# 后端真实的Pod服务节点【Pod的IP地址+虚端口】
Session Affinity:  None
Events:            <none>

如上,我们可以看到,分配的ClusterIP为10.109.113.53,我们可以通过ClusterIP访问:

$ curl 10.109.113.53:80
hello, this request is from 192.168.0.6

$ curl 10.109.113.53:80
hello, this request is from 192.168.1.3

可以看到,发起两次请求,请求会被负载均衡到两个不同的Pod,这就是Service提供的负载均衡功能。

5.2、NodePort

$ kubectl create deployment nginx --image=nginx

# 暴露端口,让集群外部可以访问,Service类型为NodePort
$ kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
nginx-748c667d99-5mf49   1/1     Running   0          6m13s   192.168.1.6   node01   <none>           <none>

$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE     SELECTOR
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        14d     <none>
nginx        NodePort    10.98.224.65   <none>        80:31853/TCP   6m13s   app=nginx

可以看到,nginx这个service分配了一个ClusterIP为10.98.224.65,该Service的虚端口为80,K8S随机分配一个nodePort端口为31853,此时要访问nginx这个服务的话,有两种方式:

5.2.1、集群内通过ClusterIP+虚端口访问

# ClusterIP: 10.98.224.65     虚端口: 80
$ curl 10.98.224.65:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

5.2.2、集群外通过NodeIP+nodePort端口访问

# Node IP地址: 192.168.1.33     nodePort端口: 31853
$ curl 192.168.1.33:31853
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

5.2.3、集群内通过Pod IP + 虚端口访问

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
nginx-748c667d99-5mf49   1/1     Running   0          11m   192.168.1.6   node01   <none>           <none>

$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        14d   <none>
nginx        NodePort    10.98.224.65   <none>        80:31853/TCP   11m   app=nginx

$ kubectl get ep
NAME         ENDPOINTS         AGE
kubernetes   172.30.1.2:6443   14d
nginx        192.168.1.6:80    11m

# Pod IP地址: 192.168.1.6    虚端口: 80
$ curl 192.168.1.6:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

5.3、ExternalName

创建ExternalName Service:

vim externalname-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: externalname-service
spec:
  type: ExternalName 			# Service类型为ExternalName
  externalName: www.baidu.com
$ kubectl apply -f externalname-service.yaml 
service/externalname-service created

$ kubectl get svc -o wide
NAME                   TYPE           CLUSTER-IP   EXTERNAL-IP     PORT(S)   AGE   SELECTOR
externalname-service   ExternalName   <none>       www.baidu.com   <none>    7s    <none>
kubernetes             ClusterIP      10.96.0.1    <none>          443/TCP   17d   <none>

$ kubectl describe svc externalname-service
Name:              externalname-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          <none>
Type:              ExternalName
IP Families:       <none>
IP:                
IPs:               <none>
External Name:     www.baidu.com
Session Affinity:  None
Events:            <none>

# 查看DNS域名解析
controlplane $ dig @10.96.0.10 externalname-service.default.svc.cluster.local

; <<>> DiG 9.16.1-Ubuntu <<>> @10.96.0.10 externalname-service.default.svc.cluster.local
; (1 server found)
;; 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: 31598
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 085781a8a4291b6d (echoed)
;; QUESTION SECTION:
;externalname-service.default.svc.cluster.local.        IN A

;; ANSWER SECTION:
externalname-service.default.svc.cluster.local. 7 IN CNAME www.baidu.com.
www.baidu.com.          7       IN      CNAME   www.a.shifen.com.
www.a.shifen.com.       7       IN      CNAME   www.wshifen.com.
www.wshifen.com.        7       IN      A       103.235.46.40

;; Query time: 4 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Mon Jan 09 09:43:29 UTC 2023
;; MSG SIZE  rcvd: 279

六、Service代理模式

6.1、userspace 代理模式

在该模式下 kube-proxy 会为每一个 Service 创建一个监听端口,发送给 Cluseter IP 请求会被 iptable 重定向给 kube-proxy 监听的端口上,其中 kube-proxy 会根据 LB 算法将请求转发到相应的pod之上。

该模式下,kube-proxy充当了一个四层负载均衡器的角色。由于kube-proxy运行在userspace中,在进行转发处理的时候会增加内核和用户空间之间的数据拷贝,虽然比较稳定,但是效率非常低下。

6.2、iptables 代理模式

iptables模式下 kube-proxy 为每一个pod创建相对应的 iptables 规则,发送给 ClusterIP 的请求会被直接发送给后端pod之上。

在该模式下 kube-proxy 不承担负载均衡器的角色,其只会负责创建相应的转发策略,该模式的优点在于较userspace模式效率更高,但是不能提供灵活的LB策略,当后端Pod不可用的时候无法进行重试。

6.3、IPVS 代理模式

IPVS模式与iptable模式类型,kube-proxy 会根据pod的变化创建相应的 IPVS转发规则,与iptalbes模式相比,IPVS模式工作在内核态,在同步代理规则时具有更好的性能,同时提高网络吞吐量为大型集群提供了更好的可扩展性,同时提供了大量的负责均衡算法。

注意:当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。

下面演示如何修改代理模式为IPVS代理模式。

6.3.1、加载ipvs相关内核模块 

modprobe ip_vs
modprobe ip_vs_rr
modprobe ip_vs_wrr
modprobe ip_vs_sh

6.3.2、编辑配置文件

实际上是修改kube-proxy对应的ConfingMap:

$ kubectl get cm -n kube-system | grep kube-proxy
NAME                                 DATA   AGE
kube-proxy                           2      14d

$ kubectl edit cm kube-proxy -n kube-system
configmap/kube-proxy edited

修改mode的值,将其修改为ipvs,如下图:

6.3.3、删除原有的kube-proxy代理 

$ kubectl get pod -A | grep kube-proxy   
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   kube-proxy-xnz4r                           1/1     Running   0          14d
kube-system   kube-proxy-zbxrb                           1/1     Running   0          14d

$ kubectl delete pod kube-proxy-xnz4r -n kube-system
pod "kube-proxy-xnz4r" deleted

$ kubectl delete pod kube-proxy-zbxrb -n kube-system
pod "kube-proxy-zbxrb" deleted

 删除完成后,k8s会自动重启kube-proxy的Pod:

$ kubectl get pod -A | grep kube-proxy     
kube-system   kube-proxy-hvnmt                           1/1     Running   0          6m35s
kube-system   kube-proxy-zp6z5                           1/1     Running   0          6m20s

6.3.4、查看IPVS

$ 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
  -> 172.30.1.2:6443              Masq    1      1          0         
TCP  10.96.0.10:53 rr
  -> 192.168.0.5:53               Masq    1      0          0         
  -> 192.168.1.2:53               Masq    1      0          0         
TCP  10.96.0.10:9153 rr
  -> 192.168.0.5:9153             Masq    1      0          0         
  -> 192.168.1.2:9153             Masq    1      0          0         
TCP  10.99.58.167:80 rr
  -> 192.168.0.6:80               Masq    1      0          0         
  -> 192.168.1.3:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 192.168.0.5:53               Masq    1      0          0         
  -> 192.168.1.2:53               Masq    1      0          0  

如上图,产生了一批转发规则。

七、HeadLiness services

在某些场景中,开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况,kubernetes提供了HeadLiness Service,这类Service不会分配Cluster IP,如果想要访问Service,只能通过Service的域名进行查询。

7.1、创建Pod

vim headliness-pod.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
              protocol: TCP
$ vim headliness-pod.yaml
$ kubectl apply -f headliness-pod.yaml 
deployment.apps/nginx created

$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE   READINESS GATES
nginx-7f456874f4-225j6   1/1     Running   0          16s   192.168.1.3   node01         <none>           <none>
nginx-7f456874f4-r7csn   1/1     Running   0          16s   192.168.0.6   controlplane   <none>           <none>

7.2、创建Service

vim headliness-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: headliness-service
spec:
  selector:
    app: nginx
  clusterIP: None 	# 将clusterIP设置为None,即可创建headliness Service
  type: ClusterIP
  ports:
    - port: 80 		# Service的端口
      targetPort: 80 		# Pod的端口
$ vim headliness-service.yaml
$ kubectl get pod -o wide --show-labels
NAME                     READY   STATUS    RESTARTS   AGE    IP            NODE           NOMINATED NODE   READINESS GATES   LABELS
nginx-7f456874f4-225j6   1/1     Running   0          103s   192.168.1.3   node01         <none>           <none>            app=nginx,pod-template-hash=7f456874f4
nginx-7f456874f4-r7csn   1/1     Running   0          103s   192.168.0.6   controlplane   <none>           <none>            app=nginx,pod-template-hash=7f456874f4

controlplane $ kubectl apply -f headliness-service.yaml 
service/headliness-service created

controlplane $ kubectl get svc -o wide --show-labels
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR    LABELS
headliness-service   ClusterIP   None         <none>        80/TCP    10s   app=nginx   <none>
kubernetes           ClusterIP   10.96.0.1    <none>        443/TCP   17d   <none>      component=apiserver,provider=kubernetes

# 查看详情
$ kubectl describe service headliness-service
Name:              headliness-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         192.168.0.6:80,192.168.1.3:80			# 能提供服务的Pod
Session Affinity:  None
Events:            <none>

7.3、进入容器,查看服务域名 

# 查看Pod
$ kubectl get pod -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
nginx-7f456874f4-225j6   1/1     Running   0          4m37s   192.168.1.3   node01         <none>           <none>
nginx-7f456874f4-r7csn   1/1     Running   0          4m37s   192.168.0.6   controlplane   <none>           <none>

# 进入Pod
$ kubectl exec nginx-7f456874f4-r7csn -it -- bin/bash

# 查看域名
root@nginx-7f456874f4-r7csn:/# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

# 通过Service的域名进行查询:默认访问规则service名称.名称空间.svc.cluster.local
# 在Pod内通过curl可以访问
root@nginx-7f456874f4-r7csn:/# curl headliness-service.default.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@nginx-7f456874f4-r7csn:/# exit
exit

# 查看DNS
$ apt install  bind9-utils

$ dig @10.96.0.10 headliness-service.default.svc.cluster.local

; <<>> DiG 9.16.1-Ubuntu <<>> @10.96.0.10 headliness-service.default.svc.cluster.local
; (1 server found)
;; 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: 59994
;; 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
; COOKIE: b633b51a4ca3a653 (echoed)
;; QUESTION SECTION:
;headliness-service.default.svc.cluster.local. IN A

;; ANSWER SECTION:
headliness-service.default.svc.cluster.local. 30 IN A 192.168.1.3
headliness-service.default.svc.cluster.local. 30 IN A 192.168.0.6

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Mon Jan 09 09:

更多推荐

【完全攻略】畅游NLP海洋:HuggingFace的快速入门

目录前言一、HuggingFace介绍1-1、HuggingFace的介绍1-2、安装二、Tokenizer分词库:分词工具2-0、加载BertTokenizer:需要传入预训练模型的名字2-1、使用Tokenizer对句子编码:2-2、使用增强Tokenizer对句子编码:2-3、批量编码单个句子:2-4、添加新词:

【Cocos Creator 3.5实现赛车游戏】10.实现汽车节点的运动逻辑

转载知识星球|深度连接铁杆粉丝,运营高品质社群,知识变现的工具项目地址:赛车小游戏-基于CocosCreator3.5版本实现:课程的源码,基于CocosCreator3.5版本实现上一节的学习后,您已经完成了对汽车节点的控制逻辑,所在在这一章您将会实现让汽车节点去响应对汽车的控制。在这之前您需要想一下真实世界中汽车的

IntelliJ IDEA 2023 年下载、安装教程、好用插件推荐

文章目录下载与安装IDEA常用插件推荐AlibabaJavaCodingGuidelines(阿里巴巴Java开发规约)KeyPromoterX(IDEA快捷键提示)Translation(翻译插件)SaveActions(优化保存插件)CodotaAIAutocomplete(代码自动提示和推荐)Autofillin

Python基于Flask的高校舆情分析,舆情监控可视化系统

目录一、前言二、使用Python爬取舆情数据1.安装requests库2.分析数据3.爬取数据三、通过代理IP提高数据爬取效率1.获取代理IP2.使用代理IP四、使用Flask框架实现舆情监控可视化系统五、使用MongoDB存储数据六、总结一、前言在当今社会,舆情监控越来越被重视。随着互联网技术的发展,我们从传统媒体渠

系统性能调优:提升服务器响应速度

🌷🍁博主猫头虎(🐅🐾)带您GotoNewWorld✨🍁🦄博客首页——🐅🐾猫头虎的博客🎐🐳《面试题大全专栏》🦕文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》🐾学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》🐅学会Gol

汽车自适应巡航系统控制策略研究

摘要自适应巡航控制系统是高级驾驶辅助系统的重要组成部分,可以有效地减轻驾驶员操作负担,提高汽车的舒适性、燃油经济性以及道路通行率,具有重要的工程应用价值。控制策略是自适应巡航系统研究的核心内容,因此针对自适应巡航系统控制策略的研究具有重要意义。本文首先针对汽车自适应巡航控制系统的功能需求进行了分析,对固定车间时距算法和

中国汽车供应商远赴德国,中国智驾方案能否远渡重洋?

作者|Amy编辑|德新今年的上海车展,中国智能汽车的进步有目共睹,吸引了大批外企高管和研发人员的关注,甚至引发了海外车企一系列的动作和调整。而在刚刚结束的慕尼黑车展,中国车企及汽车供应链把「肌肉」秀到了现代汽车起源地——德国。此次在慕尼黑举办的IAAMOBILITY是世界五大车展之一,也是欧洲规模最大的国际性车展。这里

基于SSM+Vue的汽车售票网站的设计与实现

末尾获取源码开发语言:JavaJava开发工具:JDK1.8后端框架:SSM前端:采用Vue技术开发数据库:MySQL5.7和Navicat管理工具结合服务器:Tomcat8.5开发软件:IDEA/Eclipse是否Maven项目:是目录一、项目简介二、系统设计设计原则三、系统项目截图客运班次管理会员充值管理购票记录管

笔记本、台式机、平板二合一?Mac、Win、Linux?

电脑选型根据日常使用的需求进行选择,笔记本、台式机、平板和二合一电脑我都有尝试过,目前而言,最适合我个人的是笔记本。笔记本如果你犹豫笔记本和台式机,选择笔记本;如果你犹豫笔记本和二合一电脑,选择笔记本。笔记本电脑比较中规中矩,是绝大多数场景下都可以作为第一或者备选方案的选择。在选择笔记本的时候,需要重点考虑如下几个因素

MySQL MHA

目录概述MHAMHA的组成MHA的特点搭建MySQLMHA配置主从复制1.关防火墙,安全机制2.修改Master、Slave1、Slave2节点的主机名3.在Master、Slave1、Slave2添加主机映射关系4.修改Master、Slave1、Slave2节点的Mysql主配置文件/etc/my.cnf5.在Ma

Mac 安装ZooKeeper+kafka基本使用

为什么Kafka依赖ZooKeeper?下面ZooKeeper基本介绍:1、基本功能ZooKeeper为分布式系统提供了一种配置管理的服务:集中管理配置,即将全局配置信息保存在ZooKeeper服务中,方便进行修改和管理,省去了手动拷贝配置的过程,同时还保证了可靠和一致性。2、命名服务在分布式系统中,经常需要对应用或者

热文推荐