kubernetes Service
參考文獻(xiàn):
https://blog.csdn.net/watermelonbig/article/details/79693962
A、k8s的Service定義了一個服務(wù)的訪問入口地址,前端的應(yīng)用通過這個入口地址訪問其背 后的一組由Pod副本組成的集群實(shí)例,來自外部的訪問請求被負(fù)載均衡到后端的各個容器應(yīng)用上。
B、Service與其后端Pod副本集群之間則是通過Label Selector來實(shí)現(xiàn)對接的;
C、而RC的作用相當(dāng)于是保證Service的服務(wù)能力和服務(wù)質(zhì)量始終處于預(yù)期的標(biāo)準(zhǔn)。Service 定義可以基于 POST 方式,請求 apiserver 創(chuàng)建新的實(shí)例。
D、一個 Service 在 Kubernetes 中是一個 REST 對象。
本文對Service的使用進(jìn)行詳細(xì)說明,包括Service的負(fù)載均衡、外網(wǎng)訪問、DNS服務(wù)的搭建、Ingress7層路由機(jī)制等。
1、Service 定義詳解
1.1 yaml格式的Service定義文件的完整內(nèi)容
apiVersion: v1
kind: Service
matadata:
name: string
namespace: string
labels:
- name: string
annotations:
- name: string
spec:
selector: []
type: string
clusterIP: string
sessionAffinity: string
ports:
- name: string
protocol: string
port: int
targetPort: int
nodePort: int
status:
loadBalancer:
ingress:
ip: string
hostname: string
1.2 對Service定義文件中各屬性的說明表
屬性名稱 | 取值類型 | 是否必須 | 取值說明 |
---|---|---|---|
version | string | Required | v1 |
kind | string | Required | Service |
metadata | object | Required | 元數(shù)據(jù) |
metadata.name | string | Required | Service名稱 |
metadata.namespace | string | Required | 命名空間,默認(rèn)為default |
metadata.labels[] | list | 自定義標(biāo)簽屬性列表 | |
metadata.annotation[] | list | 自定義注解屬性列表 | |
spec | object | Required | 詳細(xì)描述 |
spec.selector[] | list | Required | Label Selector配置,將選擇具有指定Label標(biāo)簽的Pod作為管理范圍 |
spec.type | string | Required | Service的類型,指定Service的訪問方式,默認(rèn)值為ClusterIP。取值范圍如下:ClusterIP: 虛擬服務(wù)的IP,用于k8s集群內(nèi)部的pod訪問,在Node上kube-proxy通過設(shè)置的Iptables規(guī)則進(jìn)行轉(zhuǎn)發(fā)。NodePort:使用宿主機(jī)的端口,使用能夠訪問各Node的外部客戶端通過Node的IP地址和端口就能訪問服務(wù)。LoadBalancer: 使用外接負(fù)載均衡器完成到服務(wù)的負(fù)載分發(fā),需要在spec.status.loadBalancer字段指定外部負(fù)載均衡器的IP地址,并同時定義nodePort和clusterIP,用于公有云環(huán)境。 |
spec.clusterIP | string | 虛擬服務(wù)的IP地址,當(dāng)type=clusterIP時,如果不指定,則系統(tǒng)進(jìn)行自動分配。也可以手工指定。當(dāng)type=LoadBalancer時,則需要指定。 | |
spec.sessionAffinity | string | 是否支持Session,可選值為ClientIP,表示將同一個源IP地址的客戶端訪問請求都轉(zhuǎn)發(fā)到同一個后端Pod。默認(rèn)值為空。 | |
spec.ports[] | list | Service需要暴露的端口列表 | |
spec.ports[].name | string | 端口名稱 | |
spec.ports[].protocol | string | 端口協(xié)議,支持TCP和UDP,默認(rèn)值為TCP | |
spec.ports[].port | int | 服務(wù)監(jiān)聽的端口號 | |
spec.ports[].targetPort | int | 需要轉(zhuǎn)發(fā)到后端Pod的端口號 | |
spec.ports[].nodePort | int | 當(dāng)spec.type=NodePort時,指定映射到物理機(jī)的端口號 | |
status | object | 當(dāng)spec.type=LoadBalancer時,設(shè)置外部負(fù)載均衡器的地址,用于公有云環(huán)境 | |
status.loadBalancer | object | 外部負(fù)載均衡器 | |
status.loadBalancer.ingress | object | 外部負(fù)載均衡器 | |
status.loadBalancer.ingress.ip | string | 外部負(fù)載均衡器的IP地址 | |
status.loadBalancer.ingress.hostname | string | 外部負(fù)載均衡器的主機(jī)名 |
2 Service, RC, Pod 架構(gòu)層次關(guān)系
3 VIP和Service 代理
3.1 kube-proxy
運(yùn)行在每個Node上的kube-proxy進(jìn)程其實(shí)就是一個智能的軟件負(fù)載均衡器,它會負(fù)責(zé)把對Service的請求轉(zhuǎn)發(fā)到后端的某個Pod實(shí)例上并在內(nèi)部實(shí)現(xiàn)服務(wù)的負(fù)載均衡與會話保持機(jī)制。Service不是共用一個負(fù)載均衡器的IP,而是被分配了一個全局唯一的虛擬IP地址,稱為Cluster IP。
在Service的整個生命周期內(nèi),它的Cluster IP不會改變。
kube-proxy 負(fù)責(zé)為 Service 實(shí)現(xiàn)了一種 VIP(虛擬 IP)的形式,而不是 ExternalName 的形式。
在k8s v1.2版本之前默認(rèn)使用userspace提供vip代理服務(wù),從 Kubernetes v1.2 起,默認(rèn)是使用 iptables 代理。
3.2 iptables 代理模式
這種模式,kube-proxy 會監(jiān)視 Kubernetes master 對 Service 對象和 Endpoints 對象的添加和移除。 對每個 Service,它會創(chuàng)建相關(guān) iptables 規(guī)則,從而捕獲到達(dá)該 Service 的 clusterIP(虛擬 IP)和端口的請求,進(jìn)而將請求重定向到 Service 的一組 backend 中的某個上面。 對于每個 Endpoints 對象,它也會創(chuàng)建 iptables 規(guī)則,這個規(guī)則會選擇一個 backend Pod。
默認(rèn)的策略是,隨機(jī)選擇一個 backend。 實(shí)現(xiàn)基于客戶端 IP 的會話親和性,可以將 service.spec.sessionAffinity 的值設(shè)置為 "ClientIP" (默認(rèn)值為 "None")。
和 userspace 代理類似,網(wǎng)絡(luò)返回的結(jié)果是,任何到達(dá) Service 的 IP:Port 的請求,都會被代理到一個合適的 backend,不需要客戶端知道關(guān)于 Kubernetes、Service、或 Pod 的任何信息。 這應(yīng)該比 userspace 代理更快、更可靠。然而,不像 userspace 代理,如果初始選擇的 Pod 沒有響應(yīng),iptables 代理能夠自動地重試另一個 Pod,所以它需要依賴 readiness probes。
4、 發(fā)布服務(wù)---type類型
對一些應(yīng)用希望通過外部(Kubernetes 集群外部)IP 地址暴露 Service。
Kubernetes ServiceTypes 允許指定一個需要的類型的 Service,默認(rèn)是 ClusterIP 類型。
Type 的取值以及行為如下:
- ClusterIP:通過集群的內(nèi)部 IP 暴露服務(wù),選擇該值,服務(wù)只能夠在集群內(nèi)部可以訪問,這也是默認(rèn)的 ServiceType。
- NodePort:通過每個 Node 上的 IP 和靜態(tài)端口(NodePort)暴露服務(wù)。NodePort 服務(wù)會路由到 ClusterIP 服務(wù),這個 ClusterIP 服務(wù)會自動創(chuàng)建。通過請求<NodeIP>:<NodePort>,可以從集群的外部訪問一個 NodePort 服務(wù)。
- LoadBalancer:使用云提供商的負(fù)載局衡器,可以向外部暴露服務(wù)。外部的負(fù)載均衡器可以路由到 NodePort 服務(wù)和 ClusterIP 服務(wù)。
- ExternalName:通過返回 CNAME 和它的值,可以將服務(wù)映射到 externalName 字段的內(nèi)容(例如, foo.bar.example.com)。 沒有任何類型代理被創(chuàng)建,這只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持。
k8s中有3種IP地址:
- Node IP: Node節(jié)點(diǎn)的IP地址,這是集群中每個節(jié)點(diǎn)的物理網(wǎng)卡的IP地址;
- Pod IP: Pod的IP地址,這是Docker Engine根據(jù)docker0網(wǎng)橋的IP地址段進(jìn)行分配的,通常是一個虛擬的二層網(wǎng)絡(luò);
- Cluster IP:Service 的IP地址,這也是一個虛擬的IP,但它更像是一個“偽造”的IP地址,因?yàn)樗鼪]有一個實(shí)體網(wǎng)絡(luò)對象,所以無法響應(yīng)ping命令。它只能結(jié)合Service Port組成一個具體的通信服務(wù)端口,單獨(dú)的Cluster IP不具備TCP/IP通信的基礎(chǔ)。
在k8s集群之內(nèi),Node IP網(wǎng)、Pod IP網(wǎng)與Cluster IP網(wǎng)之間的通信采用的是k8s自己設(shè)計的一種編程實(shí)現(xiàn)的特殊的路由規(guī)則,不同于常見的IP路由實(shí)現(xiàn)
5、 服務(wù)發(fā)現(xiàn)
Kubernetes 支持2種基本的服務(wù)發(fā)現(xiàn)模式 —— 環(huán)境變量和 DNS。
環(huán)境變量
當(dāng) Pod 運(yùn)行在 Node 上,kubelet 會為每個活躍的 Service 添加一組環(huán)境變量。 它同時支持 Docker links兼容 變量、簡單的 {SVCNAME}_SERVICE_HOST 和 {SVCNAME}_SERVICE_PORT 變量,這里 Service 的名稱需大寫,橫線被轉(zhuǎn)換成下劃線。
舉個例子,一個名稱為 "redis-master" 的 Service 暴露了 TCP 端口 6379,同時給它分配了 Cluster IP 地址 10.0.0.11,這個 Service 生成了如下環(huán)境變量:
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
這意味著需要有順序的要求 —— Pod 想要訪問的任何 Service 必須在 Pod 自己之前被創(chuàng)建,否則這些環(huán)境變量就不會被賦值。DNS 并沒有這個限制。
DNS
一個強(qiáng)烈推薦的集群插件 是 DNS 服務(wù)器。 DNS 服務(wù)器監(jiān)視著創(chuàng)建新 Service 的 Kubernetes API,從而為每一個 Service 創(chuàng)建一組 DNS 記錄。 如果整個集群的 DNS 一直被啟用,那么所有的 Pod 應(yīng)該能夠自動對 Service 進(jìn)行名稱解析。
例如,有一個名稱為 "my-service" 的 Service,它在 Kubernetes 集群中名為 "my-ns" 的 Namespace 中,為 "my-service.my-ns" 創(chuàng)建了一條 DNS 記錄。 在名稱為 "my-ns" 的 Namespace 中的 Pod 應(yīng)該能夠簡單地通過名稱查詢找到 "my-service"。 在另一個 Namespace 中的 Pod 必須限定名稱為 "my-service.my-ns"。 這些名稱查詢的結(jié)果是 Cluster IP。
Kubernetes 也支持對端口名稱的 DNS SRV(Service)記錄。 如果名稱為 "my-service.my-ns" 的 Service 有一個名為 "http" 的 TCP 端口,可以對 "_http._tcp.my-service.my-ns" 執(zhí)行 DNS SRV 查詢,得到 "http" 的端口號。
Kubernetes DNS 服務(wù)器是唯一的一種能夠訪問 ExternalName 類型的 Service 的方式。 更多信息可以查看DNS Pod 和 Service。
Kubernetes 從 1.3 版本起, DNS 是內(nèi)置的服務(wù),通過插件管理器 集群插件 自動被啟動。Kubernetes DNS 在集群中調(diào)度 DNS Pod 和 Service ,配置 kubelet 以通知個別容器使用 DNS Service 的 IP 解析 DNS 名字。
6、 Service的基本用法
????一般來說,對外提供服務(wù)的應(yīng)用程序需要通過某種機(jī)制來實(shí)現(xiàn),對于容器應(yīng)用最簡便的方式就是通過TCP/IP機(jī)制及監(jiān)聽IP和端口號來實(shí)現(xiàn)。
創(chuàng)建一個基本功能的Service
(1) 例如,我們定義一個提供web服務(wù)的RC,由兩個tomcat容器副本組成,每個容器通過containerPort設(shè)置提供服務(wù)號為8080:
webapp-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: webapp
spec:
replicas: 2
template:
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
創(chuàng)建該RC
kubectl create -f webapp-rc.yaml
獲取Pod的IP地址:
[root@master service]# kubectl get pods -l app=webapp -o yaml| grep podIP | grep -v cni
podIP: 192.168.2.94
podIP: 192.168.1.73
[root@master service]#
直接通過這兩個Pod的IP地址和端口號訪問Tomcat服務(wù):
[root@master service]# curl 192.168.2.94:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Apache Tomcat/8.5.34</title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="tomcat.css" rel="stylesheet" type="text/css" />
</head>
........
說明可以直接通過podIP進(jìn)行訪問
直接通過Pod的IP地址和端口號可以訪問容器內(nèi)的應(yīng)用服務(wù),但是Pod的IP地址是不可靠的,例如Pod所在的Node發(fā)生故障,Pod將被k8s重新調(diào)度到另一臺Node。Pod的IP地址將發(fā)生變化,更重要的是,如果容器應(yīng)用本身是分布式的部署方式,通過多個實(shí)例共同提供服務(wù),就需要在這些實(shí)例的前端設(shè)置一個負(fù)載均衡器來實(shí)現(xiàn)請求的分發(fā)。kubernetes中的Service就是設(shè)計出來用于解決這些問題的核心組件。
(2) 為了讓客戶端應(yīng)用能夠訪問到兩個Tomcat Pod 實(shí)例,需要創(chuàng)建一個Service來提供服務(wù)
k8s提供了一種快速的方法,即通過kubectl expose命令來創(chuàng)建:
[root@master service]# kubectl expose deployment webapp
service/webapp exposed
查看新創(chuàng)建的Service可以看到系統(tǒng)為它分配了一個虛擬的IP地址(clusterIP),而Service所需的端口號則從Pod中的containerPort復(fù)制而來:
[root@master service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d10h
webapp ClusterIP 10.103.4.220 <none> 8080/TCP 5s
[root@master service]#
接下來,我們就可以通過Service的IP地址和Service的端口號訪問該Service了:
這里,對Service地址10.103.4.220:8080的訪問被自動負(fù)載分發(fā)到了后端兩個Pod之一。
(3) 除了使用kubectl expose命令創(chuàng)建Service,我們也可以通過配置文件定義Service,再通過kubectl create命令進(jìn)行創(chuàng)建
例如前面的webapp就用,我們可以設(shè)置一個Service:
webapp-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- port: 8081
targetPort: 8080
selector:
app: webapp
本例中ports定義部分指定了Service所需的虛擬端口號為8081,由于與Pod容器端口號8080不一樣,所以需要在通過targetPort來指定后端Pod的端口
selector定義部分設(shè)置的是后端Pod所擁有的label: app=webapp
(4) 目前kubernetes提供了兩種負(fù)載分發(fā)策略:RoundRobin和SessionAffinity
- RoundRobin:輪詢模式,即輪詢將請求轉(zhuǎn)發(fā)到后端的各個Pod上
- SessionAffinity:基于客戶端IP地址進(jìn)行會話保持的模式,第一次客戶端訪問后端某個Pod,之后的請求都轉(zhuǎn)發(fā)到這個Pod上
默認(rèn)是RoundRobin模式。
7、 多端口Service
有時候,一個容器應(yīng)用提供多個端口服務(wù),可以按下面這樣定義:
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
ports:
- name: web
port: 8080
targetPort: 8080
- name: management
port: 8005
targetPort: 8005
selector:
app: webapp
另一個例子是兩個端口使用了不同的4層協(xié)議,即TCP和UDP
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 10.10.10.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
8、 Headless Service
有時不需要或不想要負(fù)載均衡,以及單獨(dú)的 Service IP。 遇到這種情況,可以通過指定 Cluster IP(spec.clusterIP)的值為 "None" 來創(chuàng)建 Headless Service。
這個選項(xiàng)允許開發(fā)人員自由尋找他們自己的方式,從而降低與 Kubernetes 系統(tǒng)的耦合性。 應(yīng)用仍然可以使用一種自注冊的模式和適配器,對其它需要發(fā)現(xiàn)機(jī)制的系統(tǒng)能夠很容易地基于這個 API 來構(gòu)建。
對這類 Service 并不會分配 Cluster IP,kube-proxy 不會處理它們,而且平臺也不會為它們進(jìn)行負(fù)載均衡和路由。僅依賴于Label Selector將后端的Pod列表返回給調(diào)用的客戶端。
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
clusterIP: None
selector:
app: nginx
這樣,Service就不再具有一個特定的ClusterIP地址,對其進(jìn)行訪問將獲得包含Label"app=nginx"的全部Pod列表,然后客戶端程序自行決定如何處理這個Pod列表。
例如, StatefulSet就是使用Headless Service為客戶端返回多個服務(wù)地址。
Lable Secector:
配置 Selector:對定義了 selector 的 Headless Service,Endpoint 控制器在 API 中創(chuàng)建了 Endpoints 記錄,并且修改 DNS 配置返回 A 記錄(地址),通過這個地址直接到達(dá) Service 的后端 Pod上。
不配置 Selector:對沒有定義 selector 的 Headless Service,Endpoint 控制器不會創(chuàng)建 Endpoints 記錄。
9、 外部服務(wù)Service——沒有 selector 的 Service
在某些環(huán)境中,應(yīng)用系統(tǒng)需要將一個外部數(shù)據(jù)庫用為后端服務(wù)進(jìn)行連接,或?qū)⒘硪粋€集群或Namespace中的服務(wù)作為服務(wù)的后端,這時可以通過創(chuàng)建一個無Label Selector的Service實(shí)現(xiàn):
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
Servcie 抽象了該如何訪問 Kubernetes Pod,但也能夠抽象其它類型的 backend,例如:
希望在生產(chǎn)環(huán)境中使用外部的數(shù)據(jù)庫集群。
希望服務(wù)指向另一個 Namespace 中或其它集群中的服務(wù)。
正在將工作負(fù)載同時轉(zhuǎn)移到 Kubernetes 集群和運(yùn)行在 Kubernetes 集群之外的 backend。
由于這個 Service 沒有 selector,就不會創(chuàng)建相關(guān)的 Endpoints 對象??梢允謩訉?Service 映射到指定的 Endpoints:
kind: Endpoints
apiVersion: v1
metadata:
name: my-service
subsets:
- addresses:
- ip: 1.2.3.4
ports:
- port: 9376
注意:Endpoint IP 地址不能是 loopback(127.0.0.0/8)、 link-local(169.254.0.0/16)、或者 link-local 多播(224.0.0.0/24)。
訪問沒有 selector 的 Service,與有 selector 的 Service 的原理相同。請求將被路由到用戶定義的 Endpoint(該示例中為 1.2.3.4:9376)。
ExternalName Service 是 Service 的特例,它沒有 selector,也沒有定義任何的端口和 Endpoint。 相反地,對于運(yùn)行在集群外部的服務(wù),它通過返回該外部服務(wù)的別名這種方式來提供服務(wù)。
kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
當(dāng)查詢主機(jī) my-service.prod.svc.CLUSTER時,集群的 DNS 服務(wù)將返回一個值為 my.database.example.com 的 CNAME 記錄。 訪問這個服務(wù)的工作方式與其它的相同,唯一不同的是重定向發(fā)生在 DNS 層,而且不會進(jìn)行代理或轉(zhuǎn)發(fā)。 如果后續(xù)決定要將數(shù)據(jù)庫遷移到 Kubernetes 集群中,可以啟動對應(yīng)的 Pod,增加合適的 Selector 或 Endpoint,修改 Service 的 type。
10、集群外部訪問Pod或Service的方法
由于Pod和Service是k8s集群范圍內(nèi)的虛擬概念,所以集群外的客戶端系統(tǒng)無法通過Pod的IP地址或者Service的虛擬IP地址和虛擬端口號訪問到它們。
為了讓外部客戶端可以訪問這些服務(wù),可以將Pod或Service的端口號映射到宿主機(jī),以使得客戶端應(yīng)用能夠通過物理機(jī)訪問容器應(yīng)用。
10.1、將容器應(yīng)用的端口號映射到物理機(jī)
(1) 通過設(shè)置容器級別的hostPort,將容器應(yīng)用的端口號映射到物理機(jī)上
文件pod-hostport.yaml
apiVersion: v1
kind: Pod
metadata:
name: webapp
labels:
app: webapp
spec:
containers:
- name: webapp
image: tomcat
ports:
- containerPort: 8080
hostPort: 8081
hostPort的值可以跟containerPort的值一樣
通過kubectl create創(chuàng)建這個Pod:
kubectl create -f pod-hostport.yaml
通過物理機(jī)的IP地址和8081端口號訪問Pod內(nèi)的容器服務(wù):
curl 172.16.91.137:8081
(2) 通過設(shè)置Pod級別的hostNetwork=true,該P(yáng)od中所有容器的端口號都將被直接映射到物理機(jī)上
設(shè)置hostWork=true時需要注意,在容器的ports定義部分如果不指定hostPort,則默認(rèn)hostPort等于containerPort,如果指定了hostPort,則hostPort必須等于containerPort的值。
文件pod-hostnetwork.yaml
apiVersion: v1
kind: Pod
metadata:
name: webapp-hostnetwork
labels:
app: webapp-hostnetwork
spec:
hostNetwork: true
containers:
- name: webapp-hostnetwork
image: tomcat
imagePullPolicy: Never
ports:
- containerPort: 8080
創(chuàng)建這個Pod:
kubectl create -f pod-hostnetwork.yaml
[root@master pod]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
webapp-77df6fff64-dhczl 1/1 Running 1 14h 192.168.2.95 slave2 <none>
webapp-77df6fff64-kpl6w 1/1 Running 1 14h 192.168.1.74 slave1 <none>
webapp-hostnetwork 1/1 Running 0 7s 172.16.91.136 slave1 <none>
通過物理機(jī)的IP地址和8080端口訪問Pod的容器服務(wù)
curl slave1:8080
10.2 將Service的端口號映射到物理機(jī)
(1) 通過設(shè)置nodePort映射到物理機(jī),同時設(shè)置Service的類型為NodePort
文件webapp-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: webapp-nodeport
spec:
type: NodePort
ports:
- port: 8090
targetPort: 8080
nodePort: 8090
selector:
app: webapp
創(chuàng)建這個Service:
kubectl create -f webapp-svc-nodeport.yaml
[root@master service]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d1h
webapp ClusterIP 10.103.4.220 <none> 8080/TCP 14h
webapp-nodeport NodePort 10.99.248.88 <none> 8090:31090/TCP 6s
通過物理機(jī)的IP和端口訪問:(4種方式訪問)
#Service的IP,即ClusterIP
curl 10.99.248.88:8090
#master的IP,
curl master:31090
curl slave1:31090
curl slave2:31090
也就是說,只要是nodePort端口,就會在物理機(jī)上開始監(jiān)聽端口號
如果訪問不通,查看下物理機(jī)的防火墻設(shè)置
同樣,對該Service的訪問也將被負(fù)載分發(fā)到后端多個Pod上
(2) 通過設(shè)置LoadBalancer映射到云服務(wù)商提供的LoadBalancer地址
這種用法僅用于在公有云服務(wù)提供商的云平臺上設(shè)置Service的場景。
status.loadBalancer.ingress.ip設(shè)置的146.148.47.155為云服務(wù)商提供的負(fù)載均衡器的IP地址。對該Service的訪問請求將會通過LoadBalancer轉(zhuǎn)發(fā)到后端的Pod上,負(fù)載分發(fā)的實(shí)現(xiàn)方式依賴云服務(wù)商提供的LoadBalancer的實(shí)現(xiàn)機(jī)制。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: Myapp
ports:
- protocol: TCP
port: 80
targetPort: 9376
nodePort: 30061
clusterIP: 10.0.171.239
loadBalancerIP: 78.11.24.19
type: LoadBalancer
status:
loadBalancer:
ingree:
- ip: 146.148.47.155