Kubernetes-Service介绍(三)-Ingress(含最新版安装踩坑实践)
前言
本篇是Kubernetes第十篇,大家一定要把環(huán)境搭建起來,看是解決不了問題的,必須實(shí)戰(zhàn)。
Kubernetes系列文章:
Kubernetes介紹 Kubernetes環(huán)境搭建 Kubernetes-kubectl介紹 Kubernetes-Pod介紹(-) Kubernetes-Pod介紹(二)-生命周期 Kubernetes-Pod介紹(三)-Pod調(diào)度 Kubernetes-Pod介紹(四)-Deployment Kubernetes-Service介紹(一)-基本概念 Kubernetes-Service介紹(二)-服務(wù)發(fā)現(xiàn)
什么需要Ingress
Service是基于四層TCP和UDP協(xié)議轉(zhuǎn)發(fā)的,而Ingress可以基于七層的HTTP和HTTPS協(xié)議轉(zhuǎn)發(fā),可以通過域名和路徑做到更細(xì)粒度的劃分,如下圖所示:
Ingress請求過程
用戶請求首先到達(dá)Ingress Controller,Ingress Controller根據(jù)Ingress的路由規(guī)則,查找到對應(yīng)的Service,進(jìn)而通過Endpoint查詢到Pod的IP地址,然后將請求轉(zhuǎn)發(fā)給Pod。
Ingress與Ingress Controller
簡單來說,Ingress Controller是負(fù)責(zé)具體轉(zhuǎn)發(fā)的組件,通過各種方式將它暴露在集群入口,外部對集群的請求流量會先到Ingress Controller,而Ingress對象是用來告訴Ingress Controller該如何轉(zhuǎn)發(fā)請求,比如哪些域名哪些Path要轉(zhuǎn)發(fā)到哪些服務(wù)等等。
Ingress Controller
Ingress Controller并不是Kubernetes自帶的組件,實(shí)際上Ingress Controller只是一個統(tǒng)稱,用戶可以選擇不同的Ingress Controller實(shí)現(xiàn),目前,由Kubernetes維護(hù)的Ingress Controller只有Google的GCE與Ingress Nginx兩個,其他還有很多第三方維護(hù)的Ingress Controller。但是不管哪一種Ingress Controller,實(shí)現(xiàn)的機(jī)制都基本一致,只是在具體配置上有差異。一般來說,Ingress Controller的形式都是一個Pod,里面跑著daemon程序和反向代理程序。daemon負(fù)責(zé)不斷監(jiān)控集群的變化,根據(jù)Ingress對象生成配置并應(yīng)用新配置到反向代理,比如Nginx Ingress就是動態(tài)生成Nginx配置,動態(tài)更新upstream,并在需要的時候重新加載應(yīng)用新配置。
Ingress
Ingress是一個API對象,和其他對象一樣,通過yaml文件來配置。Ingress通過Http或Https暴露集群內(nèi)部Service,給Service提供外部URL、負(fù)載均衡、SSL/TLS能力以及基于Host代理。
Ingress的部署
Deployment+LoadBalancer模式的Service
如果要把Ingress部署在公有云,那可以選擇這種方式。用Deployment部署Ingress Controller,創(chuàng)建一個type為LoadBalancer的Service關(guān)聯(lián)這組Pod。大部分公有云,都會為LoadBalancer的Service自動創(chuàng)建一個負(fù)載均衡器,通常還綁定了公網(wǎng)地址。只要把域名解析指向該地址,就實(shí)現(xiàn)了集群服務(wù)的對外暴露。此方案確定需要在公有云上部署。
Deployment+NodePort模式的Service
使用Deployment模式部署Ingress Controller,并創(chuàng)建對應(yīng)的服務(wù),但是type為NodePort。這樣,Ingress就會暴露在集群節(jié)點(diǎn)ip的特定端口上。由于Nodeport暴露的端口是隨機(jī)端口,一般會在前面再搭建一套負(fù)載均衡器來轉(zhuǎn)發(fā)請求。該方式一般用于宿主機(jī)是相對固定IP地址。
缺點(diǎn):
NodePort方式暴露Ingress雖然簡單方便,但是NodePort多了一層轉(zhuǎn)發(fā),在請求量級很大時可能對性能會有一定影響; 請求節(jié)點(diǎn)會是類似http://www.a.com:3008,其中3008是Ingress Nginx的svc暴露出來的Nodeport端口,看起來不太專業(yè);
DaemonSet+HostNetwork+NodeSelector模式
使用DaemonSet結(jié)合Nodeselector來部署Ingress Controller到特定的Node上,然后使用HostNetwork直接把該P(yáng)od與宿主機(jī)Node的網(wǎng)絡(luò)打通,直接使用宿主機(jī)的80/433端口就能訪問服務(wù)。這時Ingress Controller所在的Node機(jī)器就是流量入口。
優(yōu)點(diǎn)
該方式整個請求鏈路最簡單,性能相對NodePort減少一層轉(zhuǎn)發(fā),因此性能更好;
缺點(diǎn)
由于直接利用宿主機(jī)節(jié)點(diǎn)的網(wǎng)絡(luò)和端口,一個Node只能部署一個Ingress Controller的pod;
部署實(shí)戰(zhàn)
關(guān)于版本問題需要注意以下幾點(diǎn):
本篇采用ingress-nginx v1.0.0,最新版本 v1.0.0適用于 Kubernetes 版本 v1.19+ ;
Kubernetes-v1.22+ 需要使用 ingress-nginx>=1.0,因?yàn)?networking.k8s.io/v1beta 已經(jīng)移除;
Deployment+NodePort模式
使用wget下載v1.0.0的deploy.yaml,該處可能由于網(wǎng)絡(luò)的原因下載不下來,大家可以在第二步下載我改好的文件;
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml
接下來我們需要修改deploy.yaml里面的鏡像文件,由于k8s.gcr.io相關(guān)的鏡像國內(nèi)都進(jìn)行屏蔽了,這里我采用了從docker官方去下載相關(guān)的鏡像文件,需要將k8s.gcr.io/ingress-nginx/controller:v1.0.0和k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0鏡像替換為willdockerhub/ingress-nginx-controller:v1.0.0和jettech/kube-webhook-certgen:v1.5.2,這里需要注意的是kube-webhook-certgen有兩處不要漏替換,此外需要在args處增加--watch-ingress-without-class=true配置,這里將修改好的文件v1.0.0-deploy.yaml上傳到網(wǎng)盤,鏈接 提取碼: sksc ;
部署nginx-ingress-controller;
kubectl apply -f v1.0.0-deploy.yaml
檢查nginx-ingress-controller創(chuàng)建的情況,這個我們會發(fā)現(xiàn)該Service是一個NodePort類型,并且被隨機(jī)分配兩個端口,分別是32368和32577,后續(xù)我們就需要通過這個端口訪問改地址信息;
#查看相關(guān)pod狀態(tài)
kubectl get pods -n ingress-nginx -owide
#查看service
kubectl get service -n ingress-nginx
創(chuàng)建Deployment和Service,這里我們就是就使用之前的nginx-deployment.yaml和nginx-service.yaml;
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: backend
replicas: 3
template:
metadata:
labels:
app: backend
spec:
containers:
- name: nginx
image: nginx:latest
resources:
limits:
memory: "128Mi"
cpu: "128m"
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
#定義后端pod標(biāo)簽為app=backend
selector:
app: backend
ports:
#service端口號
- port: 80
#pod的端口號
targetPort: 80
kubectl apply -f nginx-service.yaml
kubectl apply -f nginx-nodeport-service.yaml
驗(yàn)證Service創(chuàng)建情況,并且可以通過Service地址訪問相關(guān)服務(wù);
#查看service狀況
kubectl get svc
#訪問服務(wù)
curl http://10.96.45.195
新建ingress策略nodeport-ingress.yaml,創(chuàng)建對應(yīng)資源;
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nodeport-ingress
namespace: default
spec:
rules:
- host: aa.bb.cc
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: nginx-service
port:
number: 80
#創(chuàng)建ingress資源
kubectl apply -f nodeport-ingress.yaml
#檢查ingress資源
kubectl get ingress
檢查資源的訪問,這里使用nginx-ingress-controller暴露的端口32368訪問服務(wù)的信息;
#第一種方案可以在對應(yīng)Node上設(shè)置host文件
echo '172.21.122.231 aa.bb.cc' >> /etc/hosts
curl aa.bb.cc:32368
#使用curl方式
curl -v http://172.21.122.231:32368 -H 'host: aa.bb.cc'
DaemonSet+HostNetwork+nodeSelector模式
清除資源;
kubectl delete -f v.1.0.0-deploy.yaml
kubectl delete -f nginx-nodeport-service.yaml
kubectl delete -f nodeport-ingress.yaml
給Node節(jié)點(diǎn)打標(biāo)簽為ingress=nginx;
kubectl label nodes demo-work-1 ingress=nginx
編輯v1.0.0-deploy.yaml,找到deployment部分,將kind變?yōu)镈aemonSet,nodeSelector節(jié)點(diǎn)選擇器變?yōu)閕ngress等于nginx,增加網(wǎng)絡(luò)為hostNetwork等于true,這里需要在args新增--watch-ingress-without-class,這樣ingress規(guī)則才能生效,這個是新版的以后不太一樣的地方,鏈接提取碼: dbag;
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.1
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 1.0.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
revisionHistoryLimit: 10
minReadySeconds: 0
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
spec:
dnsPolicy: ClusterFirst
containers:
- name: controller
image: willdockerhub/ingress-nginx-controller:v1.0.0
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
args:
- /nginx-ingress-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --watch-ingress-without-class=true # 新增
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 101
allowPrivilegeEscalation: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
volumeMounts:
- name: webhook-cert
mountPath: /usr/local/certificates/
readOnly: true
resources:
requests:
cpu: 100m
memory: 90Mi
nodeSelector:
ingress: nginx
hostNetwork: true
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
部署和檢查ingress-nginx;
#部署ingress-nginx
kubectl apply -f v1.0.0-deploy.yaml
#查看相關(guān)pod狀態(tài)
kubectl get pods -n ingress-nginx -owide
#查看service
kubectl get service -n ingress-nginx
新建nginx-service.yaml,將方式改變?yōu)镃lusterIP形式;
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
#定義后端pod標(biāo)簽為app=backend
selector:
app: backend
ports:
#service端口號
- port: 80
#pod的端口號
targetPort: 80
創(chuàng)建nginx-service,并檢查資源情況;
#創(chuàng)建nginx-service
kubectl apply -f nginx-service.yaml
#檢查資源狀況
kubectl get svc
#資源的綁定情況
kubectl describe service nginx-service
#通過curl訪問
curl 10.96.53.148
創(chuàng)建hostnetwork-ingress.yaml文件;
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nodeport-ingress
namespace: default
spec:
rules:
- host: aa.bb.cc
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: nginx-service
port:
number: 80
創(chuàng)建ingress資源;
#創(chuàng)建ingress
kubectl apply -f hostnetwork-ingress.yaml
#檢查ingress資源
kubectl get ingress
檢查資源的訪問;
curl -v http://172.21.122.231 -H 'host: aa.bb.cc'
結(jié)束
歡迎大家點(diǎn)點(diǎn)關(guān)注,點(diǎn)點(diǎn)贊!
總結(jié)
以上是生活随笔為你收集整理的Kubernetes-Service介绍(三)-Ingress(含最新版安装踩坑实践)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端——CSS笔记
- 下一篇: 机器学习——HMM & CRF