文章目錄

怎么跟你說 Service的出現,就是 解決ip不固定的問題 ,怎么解決呢 ? 聽小劉慢慢道來
當Pod宕機后重新生成時,其IP等狀態資訊可能會變動,Service會根據Pod的Label對這些狀態資訊進行監控和變更,保證上游服務不受Pod的變動而影響,
一、Service 簡介
1.1 Service 概念
Kubernetes Service定義了這樣一種抽象: Service是一種可以訪問 Pod邏輯分組的策略, Service通常是通過 Label Selector訪問 Pod組,
Service能夠提供負載均衡的能力,但是在使用上有以下限制:只提供 4 層負載均衡能力,而沒有 7 層功能,但有時我們可能需要更多的匹配規則來轉發請求,這點上 4 層負載均衡是不支持的

s 1.2 Service 型別
Service在 K8s中有以下四種型別:
① ClusterIp
默認型別,自動分配一個僅 Cluster內部可以訪問的虛擬 IP

② NodePort
在 ClusterIP基礎上為 Service在每臺機器上系結一個埠,這樣就可以通過 : NodePort來訪問該服務,

③ LoadBalancer
在 NodePort的基礎上,借助 Cloud Provider創建一個外部負載均衡器,并將請求轉發到 NodePort

④ ExternalName
把集群外部的服務引入到集群內部來,在集群內部直接使用,沒有任何型別代理被創建,這只有 Kubernetes 1.7或更高版本的 kube-dns才支持,
1.3 Service 基礎導論

- 客戶端訪問節點時通過
iptables實作的 iptables規則是通過kube-proxy寫入的apiserver通過監控kube-proxy去進行對服務和端點的監控kube-proxy通過pod的標簽(lables)去判斷這個斷點資訊是否寫入到Endpoints里

二、代理
2.1 VIP 和 Service 代理
在 Kubernetes集群中,每個 Node運行一個 kube-proxy行程, kube-proxy負責為 Service實作了一種 VIP(虛擬 IP)的形式,而不是 ExternalName的形式,在 Kubernetes v1.0版本,代理完全在 userspace,在 Kubernetes v1.1版本,新增了 iptables代理,但并不是默認的運行模式,從 Kubernetes v1.2起,默認就是 iptables代理,在 Kubernetes v1.8.0-beta.0中,添加了 ipvs代理,
在 Kubernetes 1.14版本開始默認使用 ipvs代理,
在 Kubernetes v1.0版本, Service是 4 層( TCP/ UDP over IP)概念,在 Kubernetes v1.1版本,新增了 Ingress API( beta版),用來表示 7 層( HTTP)服務
為何不使用 round-robin DNS?
DNS會在很多的客戶端里進行快取,很多服務在訪問 DNS進行域名決議完成、得到地址后不會對 DNS的決議進行清除快取的操作,所以一旦有他的地址資訊后,不管訪問幾次還是原來的地址資訊,導致負載均衡無效
2.2 代理模式分類
① userspace 代理模式

② iptables 代理模式

③ ipvs 代理模式
ipvs代理模式中 kube-proxy會監視 Kubernetes Service物件和 Endpoints,呼叫 netlink介面以相應地創建 ipvs規則并定期與 Kubernetes Service物件和 Endpoints物件同步 ipvs規則,以確保 ipvs狀態與期望一致,訪問服務時,流量將被重定向到其中一個后端 Pod,
與 iptables類似, ipvs于 netfilter的 hook功能,但使用哈希表作為底層資料結構并在內核空間中作業,這意味著 ipvs可以更快地重定向流量,并且在同步代理規則時具有更好的性能,此外, ipvs為負載均衡演算法提供了更多選項,例如:
rr:輪詢調度lc:最小連接數dh:目標哈希sh:源哈希sed:最短期望延遲nq:不排隊調度

三、Service 使用
3.1 ClusterIp
ClusterIP主要在每個 node節點使用 iptables,將發向 ClusterIP對應埠的資料,轉發到 kube-proxy中,然后 kube-proxy自己內部實作有負載均衡的方法,并可以查詢到這個 service下對應 pod的地址和埠,進而把資料轉發給對應的 pod的地址和埠,

為了實作圖上的功能,主要需要以下幾個組件的協同作業:
- apiserver:用戶通過
kubectl命令向apiserver發送創建service的命令,apiserver接收到請求后將資料存盤到etcd中 - kube-proxy:
Kubernetes的每個節點中都有一個叫做kube-porxy的行程,這個行程負責感知service、pod的變化,并將變化的資訊寫入本地的iptables規則中 - iptables:使用
NAT等技術將virtualIP的流量轉至endpoint中
創建 myapp-deploy.yaml檔案
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: stabel
template:
metadata:
labels:
app: myapp
release: stabel
env: test
spec:
containers:
- name: myapp
image: wangyanglinux/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
創建 Service資訊:
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: ClusterIP
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
執行命令:
[root@master service]
deployment.apps/myapp-deploy created
[root@master service]
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-deploy-6cc7c66999-5n2dj 1/1 Running 0 16s 10.244.1.26 worker1 <none> <none>
myapp-deploy-6cc7c66999-dfgqb 1/1 Running 0 16s 10.244.1.27 worker1 <none> <none>
myapp-deploy-6cc7c66999-wz6zk 1/1 Running 0 16s 10.244.2.30 worker2 <none> <none>
[root@master service]
Hello MyApp | Version: v2 | <a href="https://www.cnblogs.com/spiritmark/archive/2020/10/22/hostname.html">Pod Name</a>
[root@master service]
service/myapp created
[root@master service]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp ClusterIP 10.104.96.7 <none> 80/TCP 8s
[root@master service]
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.104.96.7:80 rr
-> 10.244.1.26:80 Masq 1 0 0
-> 10.244.1.27:80 Masq 1 0 1
-> 10.244.2.30:80 Masq 1 0 1
[root@master service]
myapp-deploy-6cc7c66999-5n2dj
[root@master service]
myapp-deploy-6cc7c66999-wz6zk
[root@master service]
myapp-deploy-6cc7c66999-dfgqb
[root@master service]
myapp-deploy-6cc7c66999-5n2dj
3.2 Handless Service
有時不需要或不想要負載均衡,以及單獨的 Service IP,遇到這種情況,可以通過指定 spec.clusterIP的值為 None來創建 Headless Service ,這類 Service并不會分配 Cluster IP, kube-proxy不會處理它們,而且平臺也不會為它們進行負載均衡和路由,
[root@master service]
apiVersion: v1
kind: Service
metadata:
name: myapp-headless
namespace: default
spec:
selector:
app: myapp
clusterIP: "None"
ports:
- port: 80
targetPort: 80
[root@master service]
3.3 NodePort
NodePort的原理在于在 Node上開了一個埠,將向該埠的流量匯入到 kube-proxy,然后由 kube-proxy進一步到給對應的 pod,
創建 Service資訊:
apiVersion: v1
kind: Service
metadata:
name: myapp
namespace: default
spec:
type: NodePort
selector:
app: myapp
release: stabel
ports:
- name: http
port: 80
targetPort: 80
執行命令:
[root@master service]
service/myapp configured
[root@master service]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp NodePort 10.104.96.7 <none> 80:30333/TCP 46m
[root@master service]
tcp6 0 0 :::30333 :::* LISTEN 3459/kube-proxy
C:\Users\MrHu>curl 192.168.182.100:30333/hostname.html
myapp-deploy-6cc7c66999-5n2dj
3.4 LoadBalancer
LoadBalancer和 NodePort其實是同一種方式,區別在于 LoadBalancer比 NodePort多了一步,就是可以呼叫 Cloud provider去創建 LB來向節點導流,

3.5 ExternalName
這種型別的 Service通過回傳 CNAME和它的值,可以將服務映射到 externalName欄位的內容( 例: hub.hc.com ), ExternalName Service是 Service的特例,它沒有 selector,也沒有定義任何的埠和 Endpoint,相反的,對于運行在集群外部的服務,它通過回傳該外部服務的別名這種方式來提供服務,
kind: Service
apiVersion: v1
metadata:
name: my-service-1
namespace: default
spec:
type: ExternalName
externalName: hub.hc.com
當查詢主機 my-service.defalut.svc.cluster.local時,集群的 DNS服務將回傳一個值 hub.hc.com的 CNAME記錄,訪問這個服務的作業方式和其他的相同,唯一不同的是重定向發生在 DNS層,而且不會進行代理或轉發,
四、Ingress
4.1 Ingress 簡介
Service只支持4層負載均衡,而Ingress有7層功能
Nginx可以通過虛擬主機域名區分不同的服務,而每個服務通過 upstream進行定義不同的負載均衡池,再加上 location進行負載均衡的反向代理,在日常使用中只需要修改 nginx.conf即可實作,但是在 K8S中又該如何實作這種方式調度呢?
K8S引入了 ingress自動進行服務的調度, ingress包含兩大組件: ingress controller和 ingress,
- ingress:修改
Nginx配置操作被抽象成了ingress物件, - ingress controller:
ingress controller通過與kubernetes API互動,動態的去感知進集群中Ingress規則變化,然后讀取它,然后讀取它,按照它自己的模板生成一段nginx配置,再寫到nginx Pod中,最后reload以下,作業流程如下圖:

Ingress 的安裝
① 下載 Ingress鏡像:
[root@master ingress]
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/kubernetes-ingress-controller/nginx-ingress-controller 0.25.0 02149b6f439f 13 months ago 508MB
② 拷貝組態檔 mandatory.yaml、 service-nodeport.yaml,位置參考 https://github.com/kubernetes/ingress-nginx/tree/nginx-0.25.0/deploy/static,
③ 部署 ingress-controller對外提供服務:
[root@master ingress]
[root@master ingress]
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-7995bd9c47-kldqr 1/1 Running 0 13h
④ 給 ingress-controller建立一個 servcie,接收集群外部流量
[root@master ingress]
[root@master ingress]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.106.6.160 <none> 80:31347/TCP,443:32445/TCP 13h
4.2 Ingress HTTP 代理訪問
創建 deployment和 svc
[root@master ingress]
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dm
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
[root@master ingress]
[root@master ingress]
NAME READY STATUS RESTARTS AGE
nginx-dm-7d967c7ff5-kvz6f 1/1 Running 0 5m20s
nginx-dm-7d967c7ff5-wk4jv 1/1 Running 0 5m21s
[root@master ingress]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.100.57.201 <none> 80/TCP 16m
創建 ingress:
[root@master ingress]
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
spec:
rules:
- host: www1.hc.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
[root@master ingress]
[root@master ingress]
NAME HOSTS ADDRESS PORTS AGE
nginx-test www1.hc.com 80 23s
[root@master ingress]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.106.6.160 <none> 80:31347/TCP,443:32445/TCP 13h
在 Window系統中配置 hosts后進行訪問:
C:\Users\MrHu>curl www1.hc.com:31347/hostname.html
nginx-dm-7d967c7ff5-wk4jv
4.3 Ingress HTTPS 代理訪問
創建證書,以及 cert存盤方式:
[root@master cert]
[root@master cert]
secret/tls-secret created
[root@master cert]
NAME TYPE DATA AGE
default-token-cjdrb kubernetes.io/service-account-token 3 6d14h
tls-secret kubernetes.io/tls
創建 deployment和 svc:
[root@master ingress]
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-https
spec:
replicas: 2
template:
metadata:
labels:
name: nginx2
spec:
containers:
- name: nginx
image: wangyanglinux/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-2
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx2
[root@master ingress]
創建 ingress:
[root@master ingress]
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-https
spec:
tls:
- hosts:
- www2.hc.com
secretName: tls-secret
rules:
- host: www2.hc.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc-2
servicePort: 80
[root@master ingress]
[root@master ingress]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc-2 ClusterIP 10.106.108.145 <none> 80/TCP 10m
[root@master ingress]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.106.6.160 <none> 80:31347/TCP,443:32445/TCP 14h
在 Window系統中配置 hosts后進行訪問:

4.4 進行 BasicAuth
[root@master ingress]
[root@master ingress]
[root@master ingress]
[root@master ingress]
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-with-auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
rules:
- host: auth.hc.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc-2
servicePort: 80
[root@master ingress]
[root@master ingress]
NAME HOSTS ADDRESS PORTS AGE
ingress-with-auth auth.hc.com 80 15s
nginx-https www2.hc.com 80, 443 23m
在 Window系統中配置 hosts后進行訪問:


4.5 Nginx進行重寫
Nginx重寫欄位:

創建 ingress:
[root@master ingress]
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-re
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://www1.hc.com:31347/hostname.html
spec:
rules:
- host: re.hc.com
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
[root@master ingress]
在 Window系統中配置 hosts后進行訪問 re.hc.com:31347:

微信搜一搜 : 全堆疊小劉 ,獲取文章 pdf 版本
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/185258.html
標籤:其他
