Service的基本介紹
Cluster IP:每個 Service 都分配了一個Cluster IP,它是一個虛擬的內部IP地址,用于在集群內部進行訪問。這個虛擬IP是由Kubernetes自動分配的,并且與Service對象一一對應。 端口映射:Service可以映射一個或多個端口到后端Pod的端口。這意味著客戶端可以通過訪問Service 的某個端口來訪問后端Pod的應用程序。 負載均衡:Service使用四層代理實現負載均衡,將來自客戶端的請求均勻地分發到后端的Pod。當多個Pod屬于同一個Service時,Service會自動將請求路由到可用的Pod上,以實現負載均衡。 DNS解析:每個Service都會自動注冊到Kubernetes集群的內置DNS中,通過服務名稱可以解
析出Service的虛擬IP。這樣,客戶端可以使用服務名稱作為域名來訪問Service,而無需知道具體的虛擬IP地址。
Kubernetes 集群中的ip地址
1 、Pod IP 地址:每個運行的Pod都會分配一個獨立的IP地址。Pod IP地址是集群內部的IP地
址,用于Pod之間的通信。
2 、Service Cluster IP 地址:Service 對象分配的虛擬IP地址稱為Cluster IP。Cluster IP是集群內部的IP地址,用于在集群內部進行服務發現和訪問。客戶端可以通過訪問Service的Cluster IP 地址來訪問與該Service相關聯的一組Pod。
3 、Node IP地址:Node(節點)是Kubernetes集群中的工作節點,每個節點都有一個IP地
址。Node IP地址用于與集群外部的網絡進行通信,例如從外部訪問集群中的服務。Node IP地
址可以是物理節點的IP地址或云提供商分配的虛擬IP地址。
這三類IP地址在Kubernetes集群中扮演不同的角色:
1 、Pod IP 地址用于Pod之間的通信,實現了容器間的網絡互通。
2 、Service Cluster IP 地址用于提供服務的訪問入口,客戶端可以通過訪問Service的Cluster IP 地址來訪問與之關聯的一組Pod。
3 、Node IP地址用于與集群外部的網絡進行通信,允許外部流量進入集群或從集群中流出。
創建Service資源
kubectl explain service
apiVersion ( string) : 表示 Service 資源使用的API版本。
kind ( string) : 表示創建的資源類型,對于Service資源,值為"Service" 。
metadata ( Object) : 包含定義Service 的元數據,例如名稱、命名空間和標簽等。
spec ( Object) : 定義 Service 的行為和規范,包含以下字段: ? allocateLoadBalancerNodePorts ( boolean) : 表示是否動態分配負載均衡器的節點端口。? clusterIP ( string) : 表示Service的Cluster IP地址,用于集群內部訪問Service,
默認由系統自動分配。
? clusterIPs ( [ ] string) : 表示Service的多個Cluster IP地址,用于集群內部訪問
Service。
? externalIPs ( [ ] string) : 表示將Service公開到集群外部的外部IP地址列表。
? externalName ( string) : 表示Service的外部名稱,用于將Service映射到外部
DNS名稱。
? externalTrafficPolicy ( string) : 表示Service外部流量的負載均衡策略,可選值為
"Local" 或"Cluster" 。
? healthCheckNodePort ( integer) : 表示健康檢查的節點端口。
? ipFamilies ( [ ] string) : 表示Service支持的IP地址族列表。
? ipFamilyPolicy ( string) : 表示Service的IP地址族策略,可選值為"SingleStack"
或"PreferDualStack" 。
? loadBalancerIP ( string) : 表示分配給負載均衡器的IP地址。
? loadBalancerSourceRanges ( [ ] string) : 表示允許訪問負載均衡器的源IP地址范
圍。
? ports ( [ ] Object) : 定義Service監聽的端口映射配置,包括協議、端口號和目標端口
等。
? publishNotReadyAddresses ( boolean) : 表示是否將未就緒的Pod的地址也發布
給Service。
? selector ( map[ string] string) : 標簽選擇器,用于選擇與Service關聯的后端Pod。
? sessionAffinity ( string) : 表示會話親和性的策略,可選值為"None" 、"ClientIP" 或
"ClientIP" 。
? sessionAffinityConfig ( Object) : 會話親和性的配置參數。
? topologyKeys ( [ ] string) : 表示用于服務拓撲感知的鍵列表。
? type ( string) : 表示Service的類型,可選值為"ClusterIP" 、
"NodePort" 、"LoadBalancer" 或"ExternalName" 。 1 . ClusterIP應用場景:
? 類型:ClusterIP是默認的Service類型。
? 應用場景:適用于集群內部的服務發現和訪問。ClusterIP將為Service分配一個虛擬
的Cluster IP地址,只能在集群內部訪問。通過該地址,其他Pod或Service可以訪
問與之關聯的一組Pod。2 .NodePort應用場景:
? 類型:NodePort類型將Service公開到集群節點上的某個固定端口。
? 應用場景:適用于需要從集群外部訪問Service的場景。通過指定NodePort類型,
Kubernetes會為Service分配一個隨機的高端口號,并將該端口映射到每個節點上。
從外部網絡,可以通過< NodeIP> :< NodePort> 的方式訪問Service。 3 .LoadBalancer:
? 類型:LoadBalancer類型通過云服務提供商的負載均衡器將Service公開到外部網
絡。
? 應用場景:適用于需要高可用性和負載均衡的場景。通過LoadBalancer類型,
Kubernetes將與云服務提供商集成,自動創建外部負載均衡器,并將流量分發到
Service關聯的Pod。外部客戶端可以通過負載均衡器的公共IP訪問Service。 4 .ExternalName:
? 類型:ExternalName類型是一種將Service映射到外部DNS名稱的方式。
? 應用場景:適用于將Service與外部服務集成的場景。通過ExternalName類型,
Service不會分配Cluster IP或NodePort,而是直接映射到一個外部DNS名稱。當
集群內部的Pod或Service訪問該Service時,DNS解析將會直接返回該外部DNS
名稱對應的IP地址。查看service的spec.ports字段如何定義? ? name: 該字段可選,用于標識端口的名稱。它在Service定義中起到描述作用,方便理解和管
理端口。
? protocol: 該字段可選,用于指定端口使用的協議,如TCP、UDP或SCTP。默認情況下,為
TCP協議。根據實際需求選擇正確的協議。
? port: 該字段必需,用于定義Service監聽的端口號。當其他Pod或Service訪問該Service
時,將使用此端口號。
? targetPort: 該字段必需,用于指定與該端口關聯的Pod容器的端口號或名稱。當請求到達
Service 后,將使用此端口號將流量轉發到后端Pod的容器端口。
? nodePort: 該字段僅在NodePort類型的Service中可選。它用于指定在每個節點上公開的端
口號。如果未指定,Kubernetes將自動分配一個端口號。通過定義Service的端口,可以實現將流量從Service端口轉發到后端Pod的容器端口。每個端口
定義可以映射到一個或多個后端Pod,實現負載均衡和服務發現的功能。根據實際需求,可以在
spec.ports 字段中定義多個端口,以滿足不同端口的訪問需求。 root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata:name: xpplabels:env: apps
spec:replicas: 3 selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:containers:- name: my-nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginxlabels:run: nginx
spec:type: NodePortports:- port: 80 protocol: TCPtargetPort: 80 nodePort: 30085 selector:run: nginx此時 已經關聯上了root@ubuntu0:~/matedata/service
Name: nginx
Namespace: default
Labels: run = nginx
Annotations: < none>
Selector: run = nginx
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.111 .189.98
IPs: 10.111 .189.98
Port: < unset> 80 /TCP
TargetPort: 80 /TCP
NodePort: < unset> 30085 /TCP
Endpoints: 10.244 .152.95:80,10.244.25.159:80,10.244.25.160:80
Session Affinity: None
External Traffic Policy: Cluster
Events: < none>
root@ubuntu0:~/matedata/service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
xpp-b6458f4cb-8spfw 1 /1 Running 0 66s 10.244 .152.95 ubuntu2 < none> < none>
xpp-b6458f4cb-jv9mn 1 /1 Running 0 66s 10.244 .25.159 ubuntu1 < none> < none>
xpp-b6458f4cb-t5prl 1 /1 Running 0 66s 10.244 .25.160 ubuntu1 < none> < none>
root@ubuntu0:~/matedata/service
kubernetes nginx
root@ubuntu0:~/matedata/service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
nginx NodePort 10.111 .189.98 < none> 80 :30085/TCP 16s
root@ubuntu0:~/matedata/service
< ! DOCTYPE html>
< html>
< head>
< title> Welcome to nginx! < /title>
< style> 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> 在創建service的時候他也會創建和service一樣的ep資源
root@ubuntu0:~/matedata
NAME ENDPOINTS AGE
kubernetes 192.168 .23.99:6443 28d
nginx 10.244 .152.95:80,10.244.25.159:80,10.244.25.160:80 23hclusterIP類型
root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata:name: xpplabels:env: apps
spec:replicas: 3 selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:containers:- name: my-nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginxlabels:run: nginx
spec:type: ClusterIPports:- port: 8080 protocol: TCPtargetPort: 80 selector:run: nginx
root@ubuntu0:~/matedata/service
Endpoints: 10.244 .152.96:80,10.244.25.161:80,10.244.25.162:80
root@ubuntu0:~/matedata/service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
nginx ClusterIP 10.105 .110.237 < none> 8080 /TCP 10s
root@ubuntu0:~/matedata/service
< ! DOCTYPE html>
< html>
< head>
< title> Welcome to nginx! < /title>
< style>
創建ExternalName類型的Service
應用場景:跨名稱空間訪問
需求:default名稱空間下的pod想要訪問nginx名稱空間下的pod服務要實現在不同命名空間下的 Pod 之間進行跨命名空間訪問,可以按照以下步驟進行操作:
第一步:在nginx名稱空間創建pod和service資源
root@ubuntu0:~
namespace/nginx created
root@ubuntu0:~
NAME STATUS AGE
default Active 29d
kube-node-lease Active 29d
kube-public Active 29d
kube-system Active 29d
nginx Active 7s
root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata: name: nginxnginx namespace: nginx
spec: replicas: 1 selector: matchLabels: web: nginx template: metadata: labels: web: nginx spec: containers: - name: nginx image: nginximagePullPolicy: IfNotPresent
root@ubuntu0:~/matedata/service
deployment.apps/nginxnginx created
root@ubuntu0:~/matedata/service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginxnginx-5f4bf9c4dc-psmnb 1 /1 Running 0 9s 10.244 .152.97 ubuntu2 < none> < none>
root@ubuntu0:~/matedata/service
apiVersion: v1
kind: Service
metadata: name: nginx-svc namespace: nginx
spec: selector: web: nginx ports: - name: http protocol: TCP port: 80 targetPort: 80
root@ubuntu0:~/matedata/service
service/nginx-svc created
root@ubuntu0:~/matedata/service
Name: nginx-svc
Namespace: nginx
Labels: < none>
Annotations: < none>
Selector: web = nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.103 .175.198
IPs: 10.103 .175.198
Port: http 80 /TCP
TargetPort: 80 /TCP
Endpoints: 10.244 .152.97:80
Session Affinity: None
Events: < none> 第二步:在default名稱空間創建pod和service資源
root@ubuntu0:~/matedata/service
apiVersion: apps/v1
kind: Deployment
metadata: name: default namespace: default
spec: replicas: 1 selector: matchLabels: app: busybox template: metadata: labels: app: busybox spec: containers: - name: busybox image: busybox:1.28 imagePullPolicy: IfNotPresent command: [ "/bin/sh" ,"-c" ,"sleep 36000" ]
root@ubuntu0:~/matedata/service
deployment.apps/default configured
root@ubuntu0:~/matedata/service
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
default-55cdb47c4-zl2x9 1 /1 Running 0 6s 10.244 .25.164 ubuntu1 < none> < none> root@ubuntu0:~/matedata/service
apiVersion: v1
kind: Service
metadata: name: client-svc
spec: type: ExternalName externalName: nginx-svc.nginx.svc.cluster.local ports: - name: http port: 80 targetPort: 80 service完整的dns名稱
service_name.svc_namespace.svc.cluster.local
root@ubuntu0:~/matedata/service
service/client-svc created
root@ubuntu0:~/matedata/service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
client-svc ExternalName < none> nginx-svc.nginx.svc.cluster.local 80 /TCP 17s
root@ubuntu0:~/matedata/service
/
Connecting to client-svc ( 10.103 .175.198:80)
index.html 100 % | *****************************************************************************************************************************************************************| 612 0 :00:00 ETA
/
wget: bad address 'nginx-svc.nginx-ns.svc.cluster.local'
/
Connecting to nginx-svc.nginx.svc.cluster.local ( 10.103 .175.198:80)
wget: can't open ' index.html': File exists
/
< ! DOCTYPE html>
< html>
< head>
< title> Welcome to nginx! < /title>
< style>
上面兩個請求的結果一樣
映射外部服務案例
k8s集群引用外部的MariaDB數據庫
在機器上安裝mariadb數據庫
root@ubuntu0:~
root@ubuntu0:~在 ubuntu0節點上創建一個名為 mysql 的目錄,并進入該目錄:
root@ubuntu0:~
root@ubuntu0:~創建一個 mysql_service.yaml 文件,并在其中定義一個類型為 ClusterIP 的 Service,用于代理外部的 MySQL 服務。設置服務監聽的端口為 3306 :
root@ubuntu0:~/mysql
apiVersion: v1
kind: Service
metadata: name: mysql
spec: type: ClusterIP ports: - port: 3306
沒寫類型默認為clusterIP類型
你會發現以上創建的svc沒有selector 沒辦法關聯后端pod,所以他的endpoint它的值為空
root@ubuntu0:~/mysql
service/mysql created
root@ubuntu0:~/mysql
Endpoints: < none>
所以需要創建一個endpoint去關聯他
root@ubuntu0:~/mysql
apiVersion: v1
kind: Endpoints
metadata: name: mysql
subsets:
- addresses: - ip: 192.168 .23.99 ports: - port: 3306
root@ubuntu0:~/mysql
endpoints/mysql created
此時就關聯上了
root@ubuntu0:~/mysql
Endpoints: 192.168 .23.99:3306通過以上步驟,我們成功在 Kubernetes 集群中引入了外部的 MySQL 數據庫。通過創建
Service 和 Endpoints,我們將外部 MySQL 的 IP 地址和端口與集群內內的 Service 進行了關聯,
使得集群內部的應用可以通過 Service 名稱訪問外部的 MySQL 服務。通過訪問該 Service,可以使用集群內的應用與外部的 MySQL 數據庫進行交互。要測試引入的數據庫是否可用,你可以在 Kubernetes 集群內的某個 Pod 中執行以下步驟:
創建一個測試用的 Pod:
root@ubuntu0:~/mysql
/
j
5.5 .5-10.6.22-MariaDB-0ubuntu0.22.04.1%Mruuk9z| t".a" ! { n4T/-1mysql_native_password
Connection closed by foreign host
/
j
5.5 .5-10.6.22-MariaDB-0ubuntu0.22.04.1& ) TK] p< zqtHUS~Ahj[ hzKGmysql_native_password8
/
j
5.5 .5-10.6.22-MariaDB-0ubuntu0.22.04.1'i& } eb= I7tui2YLP+( 8