K8s Service服务发布方式
作者:大新屋
一、Label和Selector
- Label:Label(标签)可以对K8s的一些对象,如Pod和节点进行“分组”。通过添加key=value格式的标签,用于区分同样的资源不同的分组。
- Selector:Selector(标签选择器)可以通过根据资源的标签查询出精确的对象信息。
1、创建Pod标签
(1)、Deployment自定义Pod标签参数说明
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
spec:
replicas: 1
selector:
matchLabels:
app: nginx # Deployment标签选择器进行选择自定义的Pod标签,不同的Deployment不能有相同的标签,与.spec.template.metadata.labelsc参数值匹配
template:
metadata:
labels:
app: nginx # 自定义Pod标签,与.spec.selector.matchLabels参数值匹配
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
name: nginx
(2)、创建两个不同标签的Pod
mkdir -p /data/yaml/label
cat > /data/yaml/label/nginx-deploy.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
disktype: hdd
template:
metadata:
labels:
app: nginx
disktype: hdd
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24
name: nginx01
ports:
- containerPort: 80
EOF
cat > /data/yaml/label/redis-deploy.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: redis-deploy
name: redis-deploy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
disktype: ssd
template:
metadata:
labels:
app: redis
disktype: ssd
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/redis:6.2.16
name: redis01
ports:
- containerPort: 6379
EOF
kubectl create -f /data/yaml/label/
kubectl get pods -n defaul
kubectl get pods -n default
(3)、Pod查询标签操作
### 查询default命名空间下Pod标签键值对 kubectl get pods -n default --show-labels ### 查询defalut命名空间下Pod标签键值对匹配app=nginx kubectl get pods -n default --show-labels -l app=nginx ### 查询default命名空间下Pod标签键值对匹配app=redis的Pod(正则过滤) kubectl get pods -l 'app in (redis)' -n default --show-labels ### 查询default命名空间下Pod标签键值对匹配app=redis并且disktype!=hhd(正则过滤) kubectl get pods -l 'app in (redis)' -n default --show-labels ### 查询default命名空间下Pod标签键(key)名匹配disktype kubectl get pods -n default --show-labels -l disktype
2、创建Service标签
(1)、创建一个Deployment Service
mkdir -p /data/yaml/label
cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
disktype: hdd
template:
metadata:
labels:
app: nginx
disktype: hdd
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24
name: nginx01
ports:
- containerPort: 80
EOF
kubectl create -f /data/yaml/label/nginx-deploy-service.yaml
kubectl get deploy -n default
kubectl get deploy -n default
kubectl get service -n default -owide
(2)、Service查询标签操作
### 查询Service已创建的标签键值对 kubectl get services -n default --show-labels kubectl get svc -n default --show-labels ### 查询Service标签键值对匹配app=nginx-service kubectl get Services -n default --show-labels -l app=nginx-service
3、创建节点标签
(1)、K8s节点创建标签
### 选择k8s集群k8s-node01、k8s-node02、k8s-node03创建自定义标签,app=erp-test自定义的labels标签键值对 kubectl get nodes kubectl label nodes k8s-node01 k8s-node02 k8s-node03 app=erp-test kubectl get nodes -l app=erp-test -owide
(2)、节点查询标签操作
### 查看节点已定义的所有标签 kubectl get node --show-labels ### 查看节点已定义的标签键值对(key=values)为app=erp-test kubectl get node --show-labels -l app=erp-test kubectl get nodes -l app=erp-test -owide ### 选择标签匹配app=erp-test的node节点(正则过滤) kubectl get node -l 'app in (erp-test)' --show-labels ### 选择标签匹配app=erp-test并且disktype!=ssd的node节点(正则过滤) kubectl get node -l 'disktype!=ssd,app in (erp-test)' --show-labels ### 选择lable的键(key)名为app的节点 kubectl get node --show-labels -l app
4、修改节点指定标签
### 修改指定节点名称的标签 kubectl label node k8s-node01 k8s-node02 subnet=30 --overwrite kubectl get node --show-labels -l subnet=30 ### 修改指定节点标签key kubectl label node -l subnet subnet=40 --overwrite kubectl get node --show-labels -l subnet=40
5、删除节点指定标签
### 删除指定节点的标签 kubectl label node k8s-node01 subnet- kubectl get node --show-labels -l subnet=40 ### 删除指定节点标签key kubectl label node -l subnet subnet- kubectl get node --show-labels -l subnet=40
6、节点创建标签并应用到Deployment和Service
(1)、K8s节点创建标签
### k8s-node01、k8s-node02、k8s-node03节点创建自定义标签system=erp kubectl get node kubectl label node k8s-node01 k8s-node02 k8s-node03 system=erp
(2)、创建Deployment和Service并匹配节点标签
### Deployment参数.spec.template.spec.nodeSelector参数添加节点自定义标签system=erp
cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
disktype: hdd
template:
metadata:
labels:
app: nginx
disktype: hdd
spec:
nodeSelector:
system: erp
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24
name: nginx01
ports:
- containerPort: 80
EOF
kubectl create -f /data/yaml/label/nginx-deploy-service.yaml
kubectl get pods -n default
kubectl get deploy -n default
kubectl get svc -n default
(3)、检查标签
### 检查节点标签 kubectl get node --show-labels kubectl get node --show-labels -l system=erp ### 检查Pod标签 kubectl get pods -n default --show-labels kubectl get pods -n default --show-labels -l app=nginx ### 检查Service标签 kubectl get svc -n default --show-labels kubectl get svc -n default --show-labels -l app=nginx-service
二、Service
提示:Kubernetes 官网Service说明文档: https://kubernetes.io/docs/concepts/services-networking/service/
每个Pod都会获取到它自己的IP地址,但是这些IP地址不总是稳定和可依赖的,这样就会导致一个问题:在Kubernetes集群中,如果一组Pod(比如后端的Pod)为其他Pod(比如前端的Pod)提供服务,那么如果它们之间使用Pod的IP地址进行通信,在Pod重建后,将无法再进行连接。
于是Kubernetes引用了Service这样一种抽象概念:逻辑上的一组Pod,即一种可以访问Pod的策略。这一组Pod能够被Service通过标签选择器访问到,之后就可以使用Service进行通信。

1、Service参数说明
apiVersion: v1 # 填写API资源版本号,通过kubectl api-resources | grep Service命令查询API资源版本号
kind: Service # 指定资源类型,Service资源类型是Service
metadata: # 包含Service的元数据
labels: # 设置Service标签
app: nginx-service # 自定义Service标签键值对
name: nginx-service # 自定义Service名称
spec: # 设置Service的规格
selector: # 设置Service调用Pod,必须与Deployment参数.spec.template.metadata.labels参数值匹配
app:nginx
ports: # 设置端口组
- protocol: TCP # 设置使用的协议,Service支持TCP、UDP、SCTP等协议,默认TCP协议
port: 80 # 自定义Service端口号,K8s集群内部访问使用的端口
targetPort: 80 # 指定Pod端口,如果targetPort为空,targetPort将被设置与Deployment参数.template.spec.containers.ports.containerPort:字段相同的值
type: ClusterIP # 设置Service类型,ClusterIP只允许K8s集群内部访问,NodePort允许K8s集群内部和外部访问,默认ClusterIP类型
### Service Type(服务类型)主要包括以下几种:
ClusterIP # K8s集群对内发布服务,只能K8s集群内部访问,默认值
NodePort # K8s集群对外发布服务,允许K8s集群外部和内部访问,通过kube-apiserver服务参数--service-node-port-range=30000-32767设置的端口范围内随机一个NodePort端口(也可以手动指定,但端口范围由kube-apiserver服务参数决定),通过kube-proxy服务把NodePort端口可以代理至后端Pod,可以通过NodePort从K8s集群外部访问到K8s集群内部的服务,格式为NodeIP:NodePort
LoadBalance # 使用云厂商提供的负载均衡器公开服务,成本较高
ExternalName # 通过返回定义的CNAME别名,没有设置任何类型的代理,需要K8s 1.7以上版本kube-dns支持
2、创建Service(ClusterIP,K8s集群对内发布服务)
提示:删除Deployment后,再重新创建Deployment,Servicer IP是不会发生变化,除非删除Service重新创建Service,这时Service IP就会发生变化
mkdir -p /data/yaml/label
cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24
name: nginx01
ports:
- containerPort: 80
EOF
kubectl create -f /data/yaml/label/nginx-deploy-service.yaml
kubectl get pods -n default
kubectl get deploy -n default
kubectl get service -n default
### 查看指定Service yaml文件参数配置
kubectl get svc nginx-service -n default -oyaml
### K8s集群内部访问Service格式,相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称
curl 10.96.107.232
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://nginx-service
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://10.96.107.232
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl nginx-service.default
3、创建Service(NodePort随机产生端口,K8s集群对外发布服务)
提示:删除Deployment后,再重新创建Deployment,Servicer IP是不会发生变化,除非删除Service重新创建Service,这时Service IP就会发生变化
提示:Service type参数值NodePort 是设置K8s集群对外发布服务,允许K8s集群外部和内部访问,通过kube-apiserver服务参数--service-node-port-range=30000-32767设置的端口范围内随机一个NodePort端口(也可以手动指定,但端口范围由kube-apiserver服务参数决定),通过kube-proxy服务把NodePort端口可以代理至后端Pod,可以通过NodePort从K8s集群外部访问到K8s集群内部的服务,格式为NodeIP:NodePort`
mkdir -p /data/yaml/label
cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24
name: nginx01
ports:
- containerPort: 80
EOF
kubectl create -f /data/yaml/label/nginx-deploy-service.yaml
kubectl get pods -n default
kubectl get deploy -n default
kubectl get service -n default
### 查看指定Service yaml文件参数配置
kubectl get svc nginx-service -n default -oyaml
### K8s集群外部主机访问Service格式: 任意一台K8s集群节点IP + 随机的NodePort端口
curl http://172.20.235.201:30926
### K8s集群内部访问Service格式(K8s集群内部包括节点和Pod):相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称
curl 10.96.107.232
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://nginx-service
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://10.96.107.232
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl nginx-service.default
### (kubernetes二进制安装)NodePort对外发布服务产生的30926是从/usr/lib/systemd/system/kube-apiserver.service配置文件--service-cluster-ip-range参数端口范围内随机产生
[root@k8s-master01 ~]# cat /usr/lib/systemd/system/kube-apiserver.service | egrep "service-node-port-range"
--service-node-port-range=30000-32767 \
4、创建Service(NodePort手动指定端口,K8s集群对外发布服务)
提示:删除Deployment后,再重新创建Deployment,Servicer IP是不会发生变化,除非删除Service重新创建Service,这时Service IP就会发生变化
提示:Service type参数值NodePort 是设置K8s集群对外发布服务,允许K8s集群外部和内部访问,通过kube-apiserver服务参数--service-node-port-range=30000-32767设置的端口范围内随机一个NodePort端口(也可以手动指定,但端口范围由kube-apiserver服务参数决定),通过kube-proxy服务把NodePort端口可以代理至后端Pod,可以通过NodePort从K8s集群外部访问到K8s集群内部的服务,格式为NodeIP:NodePort
mkdir -p /data/yaml/label
cat > /data/yaml/label/nginx-deploy-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 31000
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy
name: nginx-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.24
name: nginx01
ports:
- containerPort: 80
EOF
kubectl create -f /data/yaml/label/nginx-deploy-service.yaml
kubectl get pods -n default
kubectl get deploy -n default
kubectl get service -n default
### 查看指定Service yaml文件参数配置
kubectl get svc nginx-service -n default -oyaml
### K8s集群外部主机访问Service格式: 任意一台K8s集群节点IP + 手动指定的NodePort端口
curl http://172.20.235.201:31000
### K8s集群内部访问Service格式(K8s集群内部包括节点和Pod):相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称
curl 10.96.107.232
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://nginx-service
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl http://10.96.107.232
kubectl exec nginx-deploy-55c5d4b47f-424tx -- curl nginx-service.default
### (kubernetes二进制安装)NodePort对外发布服务产生的31000是从/usr/lib/systemd/system/kube-apiserver.service配置文件--service-cluster-ip-range参数端口范围内手动指定
[root@k8s-master01 ~]# cat /usr/lib/systemd/system/kube-apiserver.service | egrep "service-node-port-range"
--service-node-port-range=30000-32767 \
三、Endpoint
Endpoint的定义
- Endpoint是Kubernetes中的一种资源,用于描述Service的实际访问点。它包含了提供服务的Pod的IP地址和端口信息。
- 这些信息是Kubernetes实现服务发现和流量分发的关键依据,通过记录具体Pod的网络信息,让外部请求能够准确找到提供服务的实例。
Endpoint的作用
- Endpoint的主要作用是将Service与后端Pod关联起来。当一个Service被创建时,Kubernetes会自动创建对应的Endpoint,将Service的流量分发到后端Pod。
- 它就像是一座桥梁,连接了抽象的服务访问入口(Service)和实际提供服务的工作负载(Pod),确保服务请求能够被正确地路由到可用的Pod实例上,实现了服务的高可用性和负载均衡。
1、Service与Endpoint参数说明
apiVersion: v1
kind: Service
metadata:
labels: # Service的metadata.labels参数值与Endpoints的metadata.labels参数值一样
app: erp-service
name: erp-service # Service的metadata.name参数值与Endpoints的metadata.name参数值一样
namespace: default
spec:
ports:
- name: http # Service的spec.ports.name参数值与Endpoints的subsets.ports.name参数值一样
port: 80 # Service的spec.ports.port参数值与Endpoints的subsets.ports.port参数值一样
protocol: TCP # Service的sepc.ports.protocol参数值与Endpoints的subsets.ports.protocol参数值一样
targetPort: 80
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
labels: # Endpoints的metadata.labels参数值与Service的metadata.labels参数值一样
app: erp-service
name: erp-service # Endpoints的metadata.name参数值与Service的metadata.name参数值一样
namespace: default
subsets: # 包含一个或多个子集,每个子集都有一个地址列表和一个端口列表
- addresses: # 包含IP 地址列表
- ip: 172.17.253.111 # K8s集群外部的一台Nginx服务器
ports:
- name: http # Endpoints的subsets.ports.name参数值与Service的spec.ports.name参数值一样
port: 80 # Endpoints的subsets.ports.port参数值与Service的spec.ports.port参数值一样
protocol: TCP # Endpoints的subsets.ports.protocol参数值与Service的sepc.ports.protocol参数值一样
2、创建Service与Endpoint代理K8s集群外部服务(IP方式)
使用场景: 通过Service与Endpoint代理K8s集群外部服务指定Service名称让K8s集群内Pod都能访问到指定Service
mkdir -p /data/yaml/label
cat > /data/yaml/label/erp-endpint.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
labels:
app: erp-service
name: erp-service
namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
labels:
app: erp-service
name: erp-service
namespace: default
subsets:
- addresses:
- ip: 172.17.253.111
ports:
- name: http
port: 80
protocol: TCP
EOF
kubectl create -f /data/yaml/label/erp-endpint.yaml
kubectl get svc -n default
kubectl get ep -n default
### K8s集群内部Pod访问Service格式(K8s集群内部包括节点和Pod):相同NameSpace命名空间下Pod访问格式:Service名称 + 端口,不相同NameSpace命名空间下Pod访问格式:Service名称 + 端口 + NameSpace名称
kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl http://10.96.97.222
kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl http://erp-service
kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl http://erp-service.default
3、创建Service代理K8s集群外部服务(域名方式)
提示:Service ExternalName参数是 Service 的一个特例,它没有 Selector,也没有定义任何端口和 Endpoint,它通过返回该外部服务的别名来提供服务。比如可以定义一个 Service,后端设置为一个外部域名,这样通过 Service 的名称即可访问到该域名
注意:需要访问Service ExternalName的Pod需要与创建Service ExternalName在同一个namespace命名空间
mkdir -p /data/yaml/label cat > /data/yaml/label/nginx-service-externalname.yaml << 'EOF' apiVersion: v1 kind: Service metadata: name: erp-service-url namespace: default spec: type: ExternalName externalName: erp.test.com #externalName: erp.test.com.kube-system.cluster.local # 让kube-system命名空间下的Pod能访问到default命名空间下的Service ExternalName EOF kubectl create -f /data/yaml/label/nginx-service-externalname.yaml kubectl get svc -n default ### 进入到任意一个Pod测试访问K8s集群外部服务 kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl erp-service-url kubectl exec nginx-deploy-55c5d4b47f-6fjkm -- curl erp-service-url.default
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
