Service是k8s的核心,通過創建Service,可以為一組具有相同功能的容器應用提供一個統一的入口地址,並將請求進行負載分發到各個容器應用上。
目錄:
Service定義詳解
Service基本用法
集群外部訪問Pod和Service
一、Service定義詳解
Service的定義比Pod簡單。
apiVersion: v1
kind: Service
metadata:
name: string
labels:
name: string
annotations:
name: string
spec:
type: string
selector:
name: string
clusterIP: string #虛擬服務ip,缺省默認分配
sessionAffinity: string #是否支持session,可選值為ClientIP,表示同一個客戶端
ports:
- name: string
protocol: string #端口協議,支持TCP、UDP,默認是TCP
port: int #宿主機端口
targetPort: int #目標Pod的端口
nodePort: int #k8s內部端口
status:
loadBalancer:
ingress:
ip: string
hostname: string
上述定義中的spec.type有兩個選項:
當為NodePort時,需要配置nodePort映射到指定端口
當為LoadBalancer,需要在status中設置外部負載均衡器
二、Service基本用法
(1)通過yaml文件創建:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
name: nginx-pod
ports:
- name: nginx-service
port: 80
targetPort: 80
nodePort: 30080
比如上述,定義了一個Service,對應的是具有key=name,value=nginx-pod這個標簽的Pod,type定義為NodePort,宿主機端口為80,對應Pod端口為80,而nodePort為30080
通過如下命令創建Service
kubectl create -f service-name.yaml
創建之后查看:
可看到Service被分配的ip,對應的port以及選擇的標簽信息
(2)負載均衡
目前k8s提供了兩種負載均衡策略:RoundRobin和SessionAffinity
1、RoundRobin:輪詢模式
2、SessionAffinity:基於客戶端IP地址進行會話保持模式,請求第一次到哪個Pod,則后續還會繼續轉發到那個Pod。
默認情況下,采用輪詢模式,但也可以 通過設置spec.sessionAffinity設置為ClientIP啟用SessionAffinity策略
接下來驗證一下默認的輪詢模式:
創建兩個具有key=name,value=nginx-pod標簽的Pod,容器內運行nginx。
nginx-one:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod1
labels:
name: nginx-pod
spec:
containers:
- name: nginx-pod1
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
nginx-two:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod2
labels:
name: nginx-pod
spec:
containers:
- name: nginx-pod2
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
創建完兩個容器之后,分別進入兩個容器修改nginx首頁的字樣。
進入容器:
kubectl exec -it nginx-pod1 /bin/bash
找到文件並進行修改,此處需要注意的是,由nginx鏡像創建的容器並不具有vim和vi這兩個編輯工具,所以這邊使用sed或echo都行
sed命令替換字符串格式是:
sed -i 's/需要被替換字符串/替換后字符串/g' file-name sed -i 's/Welcome to nginx!/Welcome to nginx-pod two!/g' /usr/share/nginx/html/index.html
修改好后在瀏覽器訪問:使用ip:nodePort訪問
可以看到,service進行了負載均衡處理。
三、集群外部訪問Pod和Service
(1)將Pod的端口號映射到宿主機
比如將上述的nginx-pod1映射到主機的20080端口:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod1
labels:
name: nginx-pod
spec:
containers:
- name: nginx-pod1
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
hostPort: 20080
然后查看此Pod在哪個節點上運行
然后在瀏覽器中訪問此節點的20080端口:
(2)通過設置Pod級別的hostNetwork=true
該Pod的所有容器的端口號都將被直接映射到宿主機上,需要注意的是,如果不指定hostPort,則默認與containerPort一樣,如果指定 ,則hostPort必須等於containerPort。
例如將上述的nginx-pod2設置hostNetwork=true
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod2
labels:
name: nginx-pod
spec:
hostNetwork: true
containers:
- name: nginx-pod2
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
查看pod創建后在哪個節點上
在瀏覽器上訪問:
(3)將Service的端口號映射到宿主機上
通過設置spec.type為NodePort,同時設置spec.ports.nodePort設置宿主機上的端口號。
例如在Service基本用法那一小節的Service定義,相應的使用也在那一節有
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
name: nginx-pod
ports:
- name: nginx-service
port: 80
targetPort: 80
nodePort: 30080
===============================
我是Liusy,一個喜歡健身的程序員。
歡迎關注微信公眾號【Liusy01】,一起交流Java技術及健身,獲取更多干貨,領取Java進階干貨,領取最新大廠面試資料,一起成為Java大神。
來都來了,關注一波再溜唄。
