K8s Service服務發(fā)布方式
一、Label和Selector
- Label:Label(標簽)可以對K8s的一些對象,如Pod和節(jié)點進行“分組”。通過添加key=value格式的標簽,用于區(qū)分同樣的資源不同的分組。
- Selector:Selector(標簽選擇器)可以通過根據資源的標簽查詢出精確的對象信息。
1、創(chuàng)建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)、創(chuàng)建兩個不同標簽的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、創(chuàng)建Service標簽
(1)、創(chuàng)建一個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已創(chuàng)建的標簽鍵值對 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、創(chuàng)建節(jié)點標簽
(1)、K8s節(jié)點創(chuàng)建標簽
### 選擇k8s集群k8s-node01、k8s-node02、k8s-node03創(chuàng)建自定義標簽,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)、節(jié)點查詢標簽操作
### 查看節(jié)點已定義的所有標簽 kubectl get node --show-labels ### 查看節(jié)點已定義的標簽鍵值對(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節(jié)點(正則過濾) kubectl get node -l 'app in (erp-test)' --show-labels ### 選擇標簽匹配app=erp-test并且disktype!=ssd的node節(jié)點(正則過濾) kubectl get node -l 'disktype!=ssd,app in (erp-test)' --show-labels ### 選擇lable的鍵(key)名為app的節(jié)點 kubectl get node --show-labels -l app
4、修改節(jié)點指定標簽
### 修改指定節(jié)點名稱的標簽 kubectl label node k8s-node01 k8s-node02 subnet=30 --overwrite kubectl get node --show-labels -l subnet=30 ### 修改指定節(jié)點標簽key kubectl label node -l subnet subnet=40 --overwrite kubectl get node --show-labels -l subnet=40
5、刪除節(jié)點指定標簽
### 刪除指定節(jié)點的標簽 kubectl label node k8s-node01 subnet- kubectl get node --show-labels -l subnet=40 ### 刪除指定節(jié)點標簽key kubectl label node -l subnet subnet- kubectl get node --show-labels -l subnet=40
6、節(jié)點創(chuàng)建標簽并應用到Deployment和Service
(1)、K8s節(jié)點創(chuàng)建標簽
### k8s-node01、k8s-node02、k8s-node03節(jié)點創(chuàng)建自定義標簽system=erp kubectl get node kubectl label node k8s-node01 k8s-node02 k8s-node03 system=erp
(2)、創(chuàng)建Deployment和Service并匹配節(jié)點標簽
### Deployment參數.spec.template.spec.nodeSelector參數添加節(jié)點自定義標簽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)、檢查標簽
### 檢查節(jié)點標簽 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地址不總是穩(wěn)定和可依賴的,這樣就會導致一個問題:在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的規(guī)格
selector: # 設置Service調用Pod,必須與Deployment參數.spec.template.metadata.labels參數值匹配
app:nginx
ports: # 設置端口組
- protocol: TCP # 設置使用的協(xié)議,Service支持TCP、UDP、SCTP等協(xié)議,默認TCP協(xié)議
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集群對內發(fā)布服務,只能K8s集群內部訪問,默認值
NodePort # K8s集群對外發(fā)布服務,允許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、創(chuàng)建Service(ClusterIP,K8s集群對內發(fā)布服務)
提示:刪除Deployment后,再重新創(chuàng)建Deployment,Servicer IP是不會發(fā)生變化,除非刪除Service重新創(chuàng)建Service,這時Service IP就會發(fā)生變化
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、創(chuàng)建Service(NodePort隨機產生端口,K8s集群對外發(fā)布服務)
提示:刪除Deployment后,再重新創(chuàng)建Deployment,Servicer IP是不會發(fā)生變化,除非刪除Service重新創(chuàng)建Service,這時Service IP就會發(fā)生變化
提示:Service type參數值NodePort 是設置K8s集群對外發(fā)布服務,允許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集群節(jié)點IP + 隨機的NodePort端口
curl http://172.20.235.201:30926
### K8s集群內部訪問Service格式(K8s集群內部包括節(jié)點和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對外發(fā)布服務產生的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、創(chuàng)建Service(NodePort手動指定端口,K8s集群對外發(fā)布服務)
提示:刪除Deployment后,再重新創(chuàng)建Deployment,Servicer IP是不會發(fā)生變化,除非刪除Service重新創(chuàng)建Service,這時Service IP就會發(fā)生變化
提示:Service type參數值NodePort 是設置K8s集群對外發(fā)布服務,允許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集群節(jié)點IP + 手動指定的NodePort端口
curl http://172.20.235.201:31000
### K8s集群內部訪問Service格式(K8s集群內部包括節(jié)點和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對外發(fā)布服務產生的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實現服務發(fā)現和流量分發(fā)的關鍵依據,通過記錄具體Pod的網絡信息,讓外部請求能夠準確找到提供服務的實例。
Endpoint的作用
- Endpoint的主要作用是將Service與后端Pod關聯(lián)起來。當一個Service被創(chuàng)建時,Kubernetes會自動創(chuàng)建對應的Endpoint,將Service的流量分發(fā)到后端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、創(chuàng)建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集群內部包括節(jié)點和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、創(chuàng)建Service代理K8s集群外部服務(域名方式)
提示:Service ExternalName參數是 Service 的一個特例,它沒有 Selector,也沒有定義任何端口和 Endpoint,它通過返回該外部服務的別名來提供服務。比如可以定義一個 Service,后端設置為一個外部域名,這樣通過 Service 的名稱即可訪問到該域名
注意:需要訪問Service ExternalName的Pod需要與創(chuàng)建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
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
如何在 K8S 中使用 Values 文件定制不同環(huán)境下的應用配置
Kubernetes是一個開源的容器編排平臺,它可以自動化容器的部署、擴展和管理,在 K8s 中,應用程序通常以容器的形式運行,這些容器被組織在不同的資源對象中,這篇文章主要介紹了如何在 K8S 中使用 Values 文件定制不同環(huán)境下的應用配置,需要的朋友可以參考下2025-03-03

