当前位置: 首页 > news >正文

K8S-Service 学习

image

  1. 什么是 Kubernetes Service?
    Service 是 Kubernetes 中用于为一组 Pod(通常是 Deployment/ReplicaSet 管理的)提供稳定访问入口的抽象对象

Pod 的 IP 是不固定的,Pod 重建后 IP 会变。
Service 提供一个“虚拟 IP”(ClusterIP),无论后端 Pod 如何变化,访问 Service 的方式不变。
Service 还实现了负载均衡,将流量分发到后端所有健康的 Pod。
2. Service 的工作原理
Service 会根据 selector(标签选择器)自动发现一组符合条件的 Pod,Service 发布的时候,通过label去找哪些Pod 可以部署这个service。
Service 在集群内部创建一个虚拟 IP(ClusterIP),所有请求都会自动转发到后端 Pod。
K8s 使用 kube-proxy 实现流量转发和负载均衡。
3. 常见 Service 类型
image

NodePort 模式
image
image
image
image


创建nodeport的yaml

azureuser@master-001:~$ cat Nodeport.yaml
apiVersion: v1
kind: Service
metadata:name: web-nodeport-svc
spec:type: NodePortselector:app: webports:- port: 80           # Service端口(集群内访问)targetPort: 80     # Pod容器端口(nginx)nodePort: 30080    # 可省略,K8s自动分配30000-32767之间的端口号,也可以手动指定。

执行并测试, Master 可以通过node的IP,pod IP访问, vnet 内部可以通过node IP 访问, 外网可以通过公网地址访问。

azureuser@master-001:~$ kubectl apply -f Nodeport.yaml
service/web-nodeport-svc created
azureuser@master-001:~$ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
nginx-deploy-f88b65dbc-54gdx   1/1     Running   0          98m
nginx-deploy-f88b65dbc-fq7db   1/1     Running   0          98m
nginx-deploy-f88b65dbc-nxss8   1/1     Running   0          98m
azureuser@master-001:~$ kubectl get service
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP        45h
nginx-svc           ClusterIP   10.102.29.115    <none>        80/TCP         3h20m
nodeport-svc        NodePort    10.101.111.134   <none>        80:30443/TCP   44h
web-clusterip-svc   ClusterIP   10.102.249.165   <none>        80/TCP         105m
web-nodeport-svc    NodePort    10.109.102.59    <none>        80:30080/TCP   13s
web-svc             ClusterIP   10.104.249.89    <none>        80/TCP         44h
azureuser@master-001:~$ kubectl describe service web-nodeport-svc
Name:                     web-nodeport-svc
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=web
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.109.102.59
IPs:                      10.109.102.59
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.1.16:80,10.244.2.20:80,10.244.2.21:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>
azureuser@master-001:~$ ip route
default via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.8 metric 100
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.8 metric 100
10.244.0.0/24 dev cni0 proto kernel scope link src 10.244.0.1
10.244.1.0/24 via 10.244.1.0 dev flannel.1 onlink
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
168.63.129.16 via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.8 metric 100
169.254.169.254 via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.8 metric 100
azureuser@master-001:~$
azureuser@master-001:~$
azureuser@master-001:~$
azureuser@master-001:~$
azureuser@master-001:~$ curl http://10.0.0.5:30080
<!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>
azureuser@master-001:~$ curl http://10.244.1.16: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>

如何让vnet 内的VM 通过pod IP 访问?
kubenet 下,仅靠 UDR 无法让 VNet 其它 VM 直通 Pod IP。必须用 NodePort、LoadBalancer Service 或切换到 Azure CNI 等原生方案。

ClusterIP 模式
ClusterIP 只能在cluster内部访问,一般用于各个service 之间的相互访问。

image

创建clusterIP的yaml文件

apiVersion: v1
kind: Service
metadata:name: web-clusterip-svc
spec:type: ClusterIPselector:app: webports:- port: 80targetPort: 80

部署yaml文件

azureuser@master-001:~$ vi svc-clusterip.yaml
azureuser@master-001:~$ vi deployment1.yaml
#可以创建成功
azureuser@master-001:~$ kubectl apply -f svc-clusterip.yaml
service/web-clusterip-svc created
azureuser@master-001:~$ kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
nginx-deploy-8556777689-2dd92   1/1     Running   0          95m
nginx-deploy-8556777689-9r8w2   1/1     Running   0          95m
nginx-deploy-8556777689-b9hwl   1/1     Running   0          95m
nginx-deploy-8556777689-h5fcm   1/1     Running   0          95m
nginx-deploy-8556777689-sm89m   1/1     Running   0          95m
azureuser@master-001:~$ kubectl get service
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP        43h
nginx-svc           ClusterIP   10.102.29.115    <none>        80/TCP         94m
nodeport-svc        NodePort    10.101.111.134   <none>        80:30443/TCP   42h
web-clusterip-svc   ClusterIP   10.102.249.165   <none>        80/TCP         13s
web-svc             ClusterIP   10.104.249.89    <none>        80/TCP         42h# 但访问测试失败azureuser@master-001:~$ kubectl run testbox --image=busybox --restart=Never --rm -it -- /bin/sh-O- http://web-clusterip-svc.default.svc.cluster.local/
If you don't see a command prompt, try pressing enter.
/ # # ? busybox ??????
/ # wget -O- http://web-clusterip-svc.default.svc.cluster.local/
Connecting to web-clusterip-svc.default.svc.cluster.local (10.102.249.165:80)
wget: can't connect to remote host (10.102.249.165): Connection refused
/ #
/ #
/ # wget -O- http://web-svc.default.svc.cluster.local/
Connecting to web-svc.default.svc.cluster.local (10.104.249.89:80)
wget: can't connect to remote host (10.104.249.89): Connection refused/ # wget -O- http://10.102.249.165
Connecting to 10.102.249.165 (10.102.249.165:80)
wget: can't connect to remote host (10.102.249.165): Connection refused^C
/ #
/ #
/ #
/ # exit
pod "testbox" deleted
pod default/testbox terminated (Error)# 查看Deployment的yaml 文件,发现label 和service的不一致,导致service 找不到pod去部署,修改label 从nginx 到appapiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploy
spec:replicas: 3selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- name: nginximage: nginx:1.25.3ports:- containerPort: 80# 更新Deployment失败,
azureuser@master-001:~$ kubectl apply -f deployment1.yaml
The Deployment "nginx-deploy" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"web"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable# 原因是selector的label 不能修改,只能删除重建azureuser@master-001:~$ kubectl delete deployment nginx-deploy
deployment.apps "nginx-deploy" deleted#删除后,原service还在,但访问不通了azureuser@master-001:~$ kubectl get service
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP        43h
nginx-svc           ClusterIP   10.102.29.115    <none>        80/TCP         101m
nodeport-svc        NodePort    10.101.111.134   <none>        80:30443/TCP   43h
web-clusterip-svc   ClusterIP   10.102.249.165   <none>        80/TCP         6m44s
web-svc             ClusterIP   10.104.249.89    <none>        80/TCP         43hazureuser@master-001:~$ kubectl get deployment
No resources found in default namespace.
azureuser@master-001:~$ kubectl apply -f deployment1.yaml
deployment.apps/nginx-deploy created
azureuser@master-001:~$ kubectl get deployment
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   3/3     3            3           3sazureuser@master-001:~$ kubectl get service
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP        43h
nginx-svc           ClusterIP   10.102.29.115    <none>        80/TCP         101m
nodeport-svc        NodePort    10.101.111.134   <none>        80:30443/TCP   43h
web-clusterip-svc   ClusterIP   10.102.249.165   <none>        80/TCP         7m25s
web-svc             ClusterIP   10.104.249.89    <none>        80/TCP         43h#重新测试,可以访问了azureuser@master-001:~$ kubectl run testbox --image=busybox --restart=Never --rm -it -- /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -O- http://10.102.249.165
Connecting to 10.102.249.165 (10.102.249.165:80)
writing to stdout
<!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>
-                    100% |*****************************************************************************************************************************************************************|   615  0:00:00 ETA
written to stdout
/ #
/ #
/ # wget -O- http://10.102.249.165
Connecting to 10.102.249.165 (10.102.249.165:80)
writing to stdout
<!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>
-                    100% |*****************************************************************************************************************************************************************|   615  0:00:00 ETA
written to stdout
/ # wget -O- http://10.102.29.115
Connecting to 10.102.29.115 (10.102.29.115:80)
wget: can't connect to remote host (10.102.29.115): Connection refused
/ #
/ #
/ # exit
pod "testbox" deleted
pod default/testbox terminated (Error)
azureuser@master-001:~$
azureuser@master-001:~$

LoadBalancer 模式

什么是 LoadBalancer Service?
LoadBalancer 类型的 Service 是 Kubernetes 提供的最直接的“对外流量入口”方式。
当你在云环境(如 Azure、AWS、GCP)创建 type=LoadBalancer 的 Service 时,Kubernetes 会自动调用云平台 API,创建一个云负载均衡器(Azure LB),并将其公网/内网 IP 作为服务入口。
云 LB 会将流量分发到后端 K8s 节点,再由 kube-proxy 转发到具体 Pod。

在 Azure 上 LoadBalancer 的工作机制
K8s Master 检测到 type=LoadBalancer 的 Service 后,调用 Azure Cloud Provider。
Azure 自动分配一个公网IP(默认)或内网IP,并创建 LB 资源。
LB 后端池自动包含所有 K8s 节点。
LB 的健康探针和转发规则自动配置好,将流量转发到各节点上对应的 NodePort,然后再由 kube-proxy 转发到 Pod。
Service 的 EXTERNAL-IP 字段变成 LB 分配的 IP,你可以直接 curl 这个地址访问服务。

测试发现,通过load balancer 去调用Azure API,要修改很多配置文件,填写很多azure认证信息,cluster还要重新部署, 整体配置起来很复杂。 测试阶段,建议手动部署Azure lb,并关联到node(VM)即可。

总结与注意事项
ClusterIP:只能在集群内部访问。
NodePort:可通过任意节点 IP+端口访问(记得放行防火墙)。
LoadBalancer:云厂商自动分配公网 IP,可直接外网访问。
Selector 必须与 Deployment 的 labels 匹配,否则无后端 Pod。

http://www.hskmm.com/?act=detail&tid=19713

相关文章:

  • docker常用命令
  • 纸浆2511
  • electron38-admin桌面端后台|Electron38+Vue3+ElementPlus管理系统
  • 长江中游干流河道崩岸特征与机理研究综述
  • 基于 Python Keras 建立 猫狗图像的精准分类
  • 《ESP32-S3使用指南—IDF版 V1.6》第四十章 图片显示实验
  • 调度算法II
  • 鸿蒙应用开发从入门到实战(十六):线性布局案例
  • SQL注入流程
  • 完整的GLFW应用程序示例
  • 物理笔记
  • 基于Python+Vue开发的商城管理系统源码+运行步骤
  • HTML5-和-CSS3-迁移即时入门-全-
  • HTML5-多人游戏开发-全-
  • HTML5-地理位置即时操作指南-全-
  • 搭建环境
  • 20250928
  • Easysearch 国产替代 Elasticsearch:8 大核心挑战解读
  • Typescript概述和思维导图
  • 9-28
  • Qt结合ffmpeg代码实现udp推流/组播推流/rtp推流/监控GB28181推流/onvif推流
  • linux防火墙firewalld
  • 很多大公司为什么禁止在SpringBoot项目中使用Tomcat?
  • Java作业动手又动脑
  • PHP 开发者必须掌握的基本 Linux 命令
  • MetaGPT实战指南:构建模拟公司运营的多智能体系统 - 教程
  • Timeplus Enterprise 3.0 (Linux, macOS) - 流处理平台
  • 《HelloGitHub》第 114 期
  • Splunk Enterprise 10.0.1 (macOS, Linux, Windows) - 搜索、分析和可视化,数据全面洞察平台
  • 读后感