日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一文帶你弄懂Kubernetes應(yīng)用訪問管理

一文帶你弄懂Kubernetes應(yīng)用訪問管理

作者:喬克 2022-09-05 09:25:53

云計算

云原生 在Kubernetes中,提供了Service和Ingress兩種對象來實現(xiàn)應(yīng)用間訪問或外部對集群應(yīng)用訪問,這兩種對象在實際的工作中會時長使用,非常重要的對象。

十載的山城網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整山城建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)公司從事“山城網(wǎng)站設(shè)計”,“山城網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

在Kubernetes中,如果僅僅是單純的部署Pod,部署Deployment,并沒有任何意義,因為我們最終的目的是要為應(yīng)用和用戶提供服務(wù)。

在Kubernetes中,提供了Service和Ingress兩種對象來實現(xiàn)應(yīng)用間訪問或外部對集群應(yīng)用訪問,這兩種對象在實際的工作中會時長使用,非常重要的對象。

Service

對于kubernetes整個集群來說,Pod的地址也可變的,也就是說如果一個Pod因為某些原因退出了,而由于其設(shè)置了副本數(shù)replicas大于1,那么該Pod就會在集群的任意節(jié)點重新啟動,這個重新啟動的Pod的IP地址與原IP地址不同,這對于業(yè)務(wù)來說,就不能根據(jù)Pod的IP作為業(yè)務(wù)調(diào)度。kubernetes就引入了Service的概念,它為Pod提供一個入口,主要通過Labels標簽來選擇后端Pod,這時候不論后端Pod的IP地址如何變更,只要Pod的Labels標簽沒變,那么 業(yè)務(wù)通過service調(diào)度就不會存在問題。

當聲明Service的時候,會自動生成一個cluster IP,這個IP是虛擬IP。我們就可以通過這個IP來訪問后端的Pod,當然,如果集群配置了DNS服務(wù),比如現(xiàn)在的CoreDNS,那么也可以通過Service的名字來訪問,它會通過DNS自動解析Service的IP地址。

Service的類型有4種,Cluster IP,LoadBalance,NodePort,ExternalName。其中Cluster IP是默認的類型。

  1. Cluster IP:通過 集群內(nèi)部IP暴露服務(wù),默認是這個類型,選擇該值,這個Service服務(wù)只能通過集群內(nèi)部訪問。
  2. LoadBalance:使用云提供商的負載均衡器,可以向外部暴露服務(wù),選擇該值,外部的負載均衡器可以路由到NodePort服務(wù)和Cluster IP服務(wù)。
  3. NodePort:顧名思義是Node基本的Port,如果選擇該值,這個Service可以通過NodeIP:NodePort訪問這個Service服務(wù),NodePort會路由到Cluster IP服務(wù),這個Cluster IP會通過請求自動創(chuàng)建。
  4. ExternalName:通過返回 CNAME 和它的值,可以將服務(wù)映射到 externalName 字段的內(nèi)容,沒有任何類型代理被創(chuàng)建,可以用于訪問集群內(nèi)其他沒有Labels的Pod,也可以訪問其他NameSpace里的Service。

kubernetes主要通過kube-proxy創(chuàng)建iptables和ipvs規(guī)則,在每個Node節(jié)點上都會創(chuàng)建這些規(guī)則。

ClusterIP

ClusterIP是Service默認的類型,只能在集群的內(nèi)部訪問,也是工作中最常用的一個類型,定義如下:

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
port: 80

其中:

  • type用戶指定Service類型。
  • ports用戶指定Service的端口。
  • selector用戶選擇后端的Pod。

如果Service暴露的端口和后端的端口不一致,還可以這樣寫:

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 8080

targetPort用于指定后端的Pod,可以直接指定端口,也可以指定后端聲明的端口名字,前提是后端必須聲明端口名,如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- name: http
containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: http

如上定義好Service并創(chuàng)建過后,會在集群生成對應(yīng)的Service和Endpoints,如下:

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.103.74.70 80/TCP 12m
$ kubectl get endpoints
NAME ENDPOINTS AGE
nginx-svc 172.16.51.208:80,172.16.51.209:80,172.16.51.237:80 12m

可以看到,endpoints的名字和service的名字一樣,而且我們并沒有創(chuàng)建endpoints,是由Kubernetes自己創(chuàng)建的。其背后的邏輯是:當我們新增Pod或者刪除Pod,是從Endpoints里添加或者剔除,Service本身是不改變的,在同一個namespace下,Service和Endpoints是通過名字進行關(guān)聯(lián)的。

所以,Endpoints其實也是一個對象,除了由Kubernetes生成還可以自己定義。在實際工作,有些場景是需要自定義Endpoints的,比如在集群外部署了一個Redis服務(wù),集群內(nèi)部想通過Service的方式進行訪問,這時候就可以通過自定義Endpints的方式實現(xiàn),如下:

kind: Service
apiVersion: v1
metadata:
name: custom-endpoint-svc
spec:
ports:
- port: 30018
protocol: TCP
name: http
type: ClusterIP
---
kind: Endpoints
apiVersion: v1
metadata:
name: custom-endpoint-svc
subsets:
- addresses:
- ip: 192.168.32.8
ports:
- port: 8080
name: http

其中,在Endpoints的subsets中用于定義目的地址和端口,需要注意的是:

  • Endpoints和Service的metadata.name須保持一致。
  • Service.spec.ports[x].name和Endpoints.subsets[x].ports[x].name須保持一致。

NodePort

如果Service的類型是NodePort,表示把Service的端口映射到了Node節(jié)點上,這時候就可以通過NodeIP:NodePort進行訪問,可以實現(xiàn)在外部對集群內(nèi)應(yīng)用進行訪問。

NodePort并不是隨便選擇的,當安裝好Kubernetes集群后,會給定一個默認的NodePort范圍,它們是從30000到32767端口,如果沒有指定特定端口,默認會從這個區(qū)間范圍內(nèi)隨機選擇一個。

一個NodePort類型的Service定義如下:

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: http

除了Type類型不一樣,其他的和定義ClusterIP類型的一樣。

當創(chuàng)建完成過后,生成的Service如下:

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc NodePort 10.103.74.70 80:32710/TCP 54m

NodePort類型的Service,既可以在集群內(nèi)部通過ClusterIP:Port進行訪問,也可以在集群外部通過NodeIP:NodePort進行訪問。如上,80:32710中,80是集群內(nèi)部端口,32710是暴露出來的節(jié)點端口。

LoadBalancer

原則上,如果要使用LoadBalancer需要云廠商的支持,因為公網(wǎng)IP這些基本都是云廠商來分配。定義如下:

apiVersion: v1
kind: Service
metadata:
labels:
app: redis
name: redis-master
spec:
clusterIP: 10.96.246.58
externalTrafficPolicy: Local
healthCheckNodePort: 32006
ports:
- name: redis
nodePort: 30997
port: 6379
protocol: TCP
targetPort: 6379
selector:
app: redis
release: redis
role: master
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 121.189.210.111

這樣就可以直接通過公網(wǎng)IP和端口(121.189.210.111:6379)進行訪問。

但是,為了在內(nèi)網(wǎng)環(huán)境也使用LoadBalancer功能,有很多開源方案,其中OpenELB是一個非常不錯的項目,我們下面可以來簡單使用一下。

OpenELB

OpenELB 之前叫 PorterLB,是為物理機(Bare-metal)、邊緣(Edge)和私有化環(huán)境設(shè)計的負載均衡器插件,可作為 ?Kubernetes、K3s、KubeSphere 的 LB 插件對集群外暴露 LoadBalancer 類型的服務(wù),現(xiàn)階段是 CNCF 沙箱項目,核心功能包括:

  • 基于 BGP 與 Layer 2 模式的負載均衡。
  • 基于路由器 ECMP 的負載均衡。
  • IP 地址池管理。
  • 使用 CRD 進行 BGP 配置。

(1)安裝 要安裝OpenELB非常簡單,直接使用以下命令即可。

$ kubectl apply -f https://raw.githubusercontent.com/openelb/openelb/master/deploy/openelb.yaml

值得注意的是,如果本地不能獲取k8s.gcr.io鏡像(需要翻墻),可以把上面的YAML文件下載下來,根據(jù)里面的注釋做相應(yīng)的鏡像替換即可。

安裝完成過后,會生成如下Pod:

$ kubectl get pod -n openelb-system 
NAME READY STATUS RESTARTS AGE
openelb-admission-create-ltfcv 0/1 Completed 0 4m19s
openelb-admission-patch-h485q 0/1 Completed 0 4m19s
openelb-keepalive-vip-7mnl7 1/1 Running 0 3m8s
openelb-manager-98764b5ff-4c58s 1/1 Running 0 4m19s

(2)配置 首先,需要為kube-proxy啟動strictARP,以便Kubernetes集群中的所有網(wǎng)卡停止響應(yīng)其他網(wǎng)卡的ARP請求,而由OpenELB來處理ARP請求。

$ kubectl edit configmap kube-proxy -n kube-system
......
ipvs:
strictARP: true
......

然后重啟kube-proxy組件,命令如下:

$ kubectl rollout restart daemonset kube-proxy -n kube-system

如果安裝 OpenELB 的節(jié)點有多個網(wǎng)卡,則需要指定 OpenELB 在二層模式下使用的網(wǎng)卡,如果節(jié)點只有一個網(wǎng)卡,則可以跳過此步驟,假設(shè)安裝了 OpenELB 的 master1 節(jié)點有兩個網(wǎng)卡(eth0 192.168.0.2 和 ens33 192.168.0.111),并且 eth0 192.168.0.2 將用于 OpenELB,那么需要為 master1 節(jié)點添加一個 annotation 來指定網(wǎng)卡:

$ kubectl annotate nodes master1 layer2.openelb.kubesphere.io/v1alpha1="192.168.0.2"

接下來就可以創(chuàng)建一個EIP對象來充當OpenELB的IP地址池,YAML清單如下:

apiVersion: network.kubesphere.io/v1alpha2
kind: Eip
metadata:
name: eip-pool
spec:
address: 192.168.205.50-192.168.205.60
protocol: layer2
disable: false
interface: ens33

值得注意的是:

  • address用于配置地址池,如果是在layer2層,則需要和集群的地址保持在同一網(wǎng)段。
  • protocol用戶指定模式,默認是bgp,我們這里指定的是layer2。
  • interface用于指定網(wǎng)卡,由于這里是layer2,所以需要指定interface。
  • disable表示禁用Eip對象

創(chuàng)建完成過后,可以看看Eip地址池狀態(tài):

$ kubectl get eip
NAME CIDR USAGE TOTAL
eip-pool 192.168.205.50-192.168.205.60 1 11

最后,我們創(chuàng)建一個LoadBalancer類型的Service,如下:

apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
annotations:
lb.kubesphere.io/v1alpha1: openelb
protocol.openelb.kubesphere.io/v1alpha1: layer2
eip.openelb.kubesphere.io/v1alpha2: eip-pool
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: http

注意這里我們?yōu)?Service 添加了幾個 annotations 注解:

  • lb.kubesphere.io/v1alpha1: openelb 用來指定該 Service 使用 OpenELB。
  • protocol.openelb.kubesphere.io/v1alpha1: layer2  表示指定 OpenELB 用于 Layer2 模式。
  • eip.openelb.kubesphere.io/v1alpha2: eip-pool 用來指定了 OpenELB 使用的 Eip 對象,如果未配置此注解,OpenELB 會自動使用與協(xié)議匹配的第一個可用 Eip 對象,此外也可以刪除此注解并添加 spec:loadBalancerIP 字段(例如 spec:loadBalancerIP: 192.168.0.108)以將特定 IP 地址分配給 Service。

Service創(chuàng)建過后,可以查看其狀態(tài)是否正確:

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc LoadBalancer 10.103.74.70 192.168.205.50 80:32710/TCP 105m

可以看到在EXTERNAL-IP處為我們分配了一個Eip,現(xiàn)在就可以直接使用192.168.205.50:80從外部直接訪問集群內(nèi)的服務(wù)了。

ExternalName

ExternalName 是 Service 的特例,它沒有 selector,也沒有定義任何的端口和 Endpoint。對于運行在集群外部的服務(wù),它通過返回該外部服務(wù)的別名這種方式來提供服務(wù)。例如:

kind: Service
apiVersion: v1
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.cdxwcx.com

當查詢主機 my-service.prod.svc.cluster.local (后面服務(wù)發(fā)現(xiàn)的時候我們會再深入講解)時,集群的 DNS 服務(wù)將返回一個值為 my.database.cdxwcx.com 的 CNAME 記錄。訪問這個服務(wù)的工作方式與其它的相同,唯一不同的是重定向發(fā)生在 DNS 層,而且不會進行代理或轉(zhuǎn)發(fā)。如果后續(xù)決定要將數(shù)據(jù)庫遷移到 Kubernetes 集群中,可以啟動對應(yīng)的 Pod,增加合適的 Selector 或 Endpoint,修改 Service 的 type,完全不需要修改調(diào)用的代碼,這樣就完全解耦了。

Headless Service

上面介紹的幾種Service的類型,都會生成一個ClusterIP供集群使用,如果在Kubernetes集群中配置了DNS,解析Service Name會得到ClusterIP。但是在一些特殊的場景下,我們希望直接和應(yīng)用Pod進行通信,比如數(shù)據(jù)庫等有狀態(tài)應(yīng)用,為此,社區(qū)提供了Headless Service,也就是無頭服務(wù)。

無頭服務(wù),也就是在配置Service的時候?qū)pec.clusterIP的值設(shè)置為“None”,如下:

apiVersion: v1
kind: Service
metadata:
name: nginx-headless-service
labels:
name: nginx-headless-service
spec:
clusterIP: None
selector:
name: nginx
ports:
- port: 8000
targetPort: 80

創(chuàng)建過后,就不會生成ClusterIP,如下:

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 17d
nginx-headless-service ClusterIP None 8000/TCP 3s

這種類型的Service主要用在有狀態(tài)服務(wù),后續(xù)在有狀態(tài)應(yīng)用管理的時候會感受到具體是如何使用的。

Ingress

上面介紹的Service主要用在集群內(nèi)部,當然NodePort和LoadBalancer類型也可以用于外部訪問,但是它們也有一定的弊端:

  1. 如果使用NodePort類型,需要維護好每個應(yīng)用的端口地址,如果服務(wù)太多就不好管理。
  2. 如果使用LoadBalancer類型,基本是在云上使用,需要的IP比較多,價格也比較昂貴。
  3. 不論是NodePort還是LoadBalancer,都是工作在四層,對于HTTPS類型的請求無法直接進行SSL校驗。

因此,社區(qū)提供了Ingress對象,為集群提供統(tǒng)一的入口,邏輯如下:

其中Ingress代理的并不是Pod的Service,而是Pod,之所以在配置的時候是配置的Service,是為了獲取Pod的信息。

Ingress提供七層訪問入口,但是Kubernetes的Ingress對象本身沒有任何功能,需要借助一些Controller來實現(xiàn),常用的有:

  • Nginx Ingress Controller
  • Traefik Ingress Controller
  • Kong Ingress Controller
  • APISix Ingress Controller
  • .....

最常用的是nginx ingress controller,這里也會安裝nginx ingress controller來進行介紹。

安裝Nginx Ingress Controller

安裝方式非常簡單,可以使用Helm和普通的YAML進行安裝,由于我們還沒有學(xué)習(xí)Helm,所以采用YAML清單的方式。

如果網(wǎng)絡(luò)條件好(可以翻墻),可直接使用以下命令安裝:

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml

如果網(wǎng)絡(luò)條件不好,可以使用:

$ kubectl apply -f https://raw.githubusercontent.com/joker-bai/kubernetes-software-yaml/main/ingress/nginx/ingress-nginx.yaml

安裝完成過后,資源信息如下:

$ kubectl get all -n ingress-nginx 
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-kj7ch 0/1 Completed 0 8m16s
pod/ingress-nginx-admission-patch-gtncg 0/1 Completed 0 8m16s
pod/ingress-nginx-controller-d5c4c7ffb-6q5gn 1/1 Running 0 8m16s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.109.208.249 192.168.205.51 80:31306/TCP,443:31079/TCP 8m16s
service/ingress-nginx-controller-admission ClusterIP 10.103.169.99 443/TCP 8m16s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 8m16s

NAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-d5c4c7ffb 1 1 1 8m16s

NAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 5s 8m16s
job.batch/ingress-nginx-admission-patch 1/1 6s 8m16s

在這里,ingress-nginx對外暴露采用的是LoadBalancer,也就是說把域名解析到192.168.205.51地址上,可以直接通過80端口訪問。

暴露第一個服務(wù)

上面已經(jīng)把ingress-nginx controller部署好了,接下來就可以創(chuàng)建一個應(yīng)用進行暴露。

我們這里通過暴露一個nginx服務(wù),如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
type: ClusterIP
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: nginx.dev.jokerbai.http://www.dlmjj.cn/article/djdgjcg.html