kubernetes service 和 ingress 薦
一 總述
1 service 作用
POD 中執行的容器存在動態、彈性的變化(容器的重啟IP地址會變化),因此便產生了service,其資源為此類POD物件提供一個固定、統一的訪問介面及負載均衡能力,並藉助DNS系統的服務發現功能,解決客戶端發現容器難得問題 service 和POD 物件的IP地址在叢集內部可達,但叢集外部使用者無法接入服務,解決的思路有: 1 在POD上做埠暴露(hostPort) 2 在工作節點上公用網路名稱空間(hostNetwork) 3 使用service 的NodePort 或 loadbalancer (service 依賴於 DNS資源服務) 4 ingress七層負載均衡和反向代理資源
2 service資源及實現模型
1 service 概述
1 service是微服務的一種實現,事實上其是一種抽象:通過關注定義出多個POD物件組合而成的邏輯集合,以及訪問這組POD的策略,service關聯POD 需要標籤選擇器完成,其基於標籤選擇器將一組POD定義成一個邏輯集合,並通過自己的IP地址和埠排程代理請求至後端POD之上。
2 service 物件的IP地址稱為cluster IP,位於K8S叢集配置指定的專用IP地址範圍內,其是一種虛擬IP地址,其在service物件建立後保持不變,並且能夠被同一叢集中的POD資源訪問,service埠接受客戶端的請求並將其轉發至後端POD中的相應埠,因此,其又被稱為四層代理,因其工作在TCP/IP層。
3 service 資源通過API server 持續監視標籤選擇器匹配到的後端POD物件,並實時跟蹤各物件的變動,service並不直接連線POD物件,而是通過endpoints 資源物件型別處理,其有IP地址和埠組成,預設情況下,當建立service物件時,其關聯的endpoints物件也會被自動建立。
2 虛擬IP和服務代理
1 虛擬IP
一個service物件就是工作節點上的一些iptables或ipvs,用於將到達service物件的IP地址的流量轉發到相應的endpoint物件指定的IP地址和埠上,kube-proxy元件通過api-server持續監控著各個service及其相關的POD物件,並將其建立或變動實時反映到工作節點的iptable或ipvs上。
ipvs是藉助於netfilter實現的網路請求報文排程框架,支援rr、wrr、lc、wlc、sh、sed和nq 等十餘種排程演算法,使用者空間的命令列工具是ipvsadm,用於管理工作於ipvs上的排程規則。
service IP 事實上是用於生成iptables 或 ipvs 規則時使用的ip地址,僅用於實現K8S叢集網路的內部通訊,並能夠通過規則中定義的轉發服務請求作為目標地址予以響應,這也是其成為虛擬IP地址的原因。
2 代理模型
1 userspace 代理模型(使用者空間模型)
userspace 是Linux作業系統的使用者空間,這種模型中,kube-proxy 負責跟蹤API server 上的endpoints物件的變動,並根據其進行相關的調整策略。
對於每個service物件,其都會隨機開啟一個本地埠,任何到達此埠的請求都會被代理到當前service資源的後端各個POD物件上,其預設使用RR排程策略。
其代理的過程是: 請求到達service後,其被轉發到核心,經由套接字送往使用者空間的kube-proxy,而後經由kube-proxy送回核心空間,並排程至後端POD,其傳輸方式效率太低。在1.1 版本之前,其是預設的轉發策略。
2 iptables代理模型
kube-proxy 負責跟蹤API server上 service和 endpoints物件的變動,並據此作出service資源定義的變動,對於每個service,都會建立iptabls規則直接捕獲到達clusterIP 和PORT 的流量,並將其重定向到當前的service後端,預設演算法是隨機排程演算法,POD 直接請求service IP 地址通過其直接訪問對應的POD服務,在1.2開始成為預設型別,其使用的是iptables的目標地址轉換至後端的POD物件,相對而言,其不用在核心和使用者空間之間切換,因此更加高效, 但其不能再被挑中的POD資源無響應時進行重定向,但使用者空間(userspace)模型可以。
3 ipvs模型
此模型跟蹤API service上的service和endpoints物件的變動,據此來呼叫netlink介面建立IPVS規則,並確保API server中的變動保持同步,其流量排程策略在IPVS中實現,其餘的在iptables中實現。
ipvs 支援眾多排程演算法,如rr、lc、dh、sh、sed和nq 等。
二 service 資源基本應用
service 本身不提供服務,其是通過後端POD提供對應的服務,因此,service資源物件通常要和deployment謝忠完成應用的建立和對外發布。
1 建立service 資源
1 使用命令列建立service資源
建立POD資源
kubectl runnginx--image=nginx:1.14--replicas=3
檢視deployment資源

其名稱為nginx
建立對應的service資源
kubectl exposedeployment nginx --name=nginx --port=80 --target-port=80 --protocol=TCP
檢視生成的service

檢視生成的endpoints對應關係

node節點資源訪問
2 使用配置檔案建立service
#[root@master1 service]# cat demo.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: service-demo namespace: default spec: selector:#用於匹配後面POD物件 matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: service-demo image: nginx:1.14 ports:# 配置暴露埠 - name: http containerPort: 80 readinessProbe:#增加就緒性探測,用於探測服務是否正常執行,若未就緒則service不能向該POD上排程流量 httpGet: port: 80 path:/index.html --- apiVersion: v1 kind: Service metadata: name: demo-service# service名稱 spec: selector:# 用於匹配後面POD物件 app: service ports: - protocol: TCP# 使用的協議 port: 80#service 埠號 targetPort: 80# 後端POD埠號
部署
kubectl apply -f demo.yaml
檢視service訪問的介面

檢視service詳細資訊
其預設型別是clusterIP,使用地址為自動配置,此型別的service物件只能通過叢集內部訪問。若叢集中的POD物件的標籤為app=service,則其會被自動關聯至service後端
建立http服務用以驗證
kubectl run http--image=httpd-l app=service
檢視POD是否啟動成功

檢視 endpoints
測試
其IP地址為service對應的IP地址
fori in1 2 3;do curl http://10.0.0.52 && echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;done
檢視

當kubernetes 叢集的service代理模式為iptables,它預設使用的演算法是隨機排程,因此service會將客戶端的請求隨機排程至關聯的某個POD資源上。
2 service 會話粘滯性
1 概述
service 會話粘滯性
service 資源支援session affinity(黏性會話或會話黏性)機制,能夠將來自同一個客戶端的請求始終轉發至同一個後端POD,其會降低負載均衡的效果,因此,當客戶端訪問POD中的應用程式時,如果有基於客戶端身份儲存某些私有資訊,並基於這些私有資訊追蹤使用者的活動一類的需求時,就應該啟動會話保持機制。
session affinity的效果會在一定時間期限內生效,預設是10800秒,超出此時間之後,客戶端的再次訪問會被排程演算法重新排程,另外service資源的session affinity 機制僅能基於客戶端IP地址識別客戶端身份,他會把經由同一個NAT 伺服器進行源地址轉換的所有客戶端識別為統一客戶端,排程粒度粗糙且效果不佳,因此,實踐中不推薦使用此種方法實現粘性會話。
2 設定欄位解析
kubectl explain service.spec.sessionAffinityConfig.clientIP.timeoutSeconds 用於配置配置其會話保持時長,是一個巢狀欄位,使用時長是1-86400,預設是10800 kubectl explain service.spec.sessionAffinity 用於定義要使用的黏性會話的型別,其僅支援"none 和"clinetIP"兩種型別。 none :不使用sessionaffinity,預設值 clientIP:基於客戶端IP地址識別客戶端身份,把來自同一個源IP地址的請求始終排程到同一個POD物件上。
3 部署例項並驗證
1 刪除上面建立例項
kubectl delete -f demo.yaml
修改例項
[root@master1 service]# cat demo1.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: service-demo namespace: default spec: selector:#用於匹配後面POD物件 matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: service-demo image: nginx:1.14 ports:# 配置暴露埠 - name: http containerPort: 80 readinessProbe:#增加就緒性探測,用於探測服務是否正常執行,若未就緒則service不能向該POD上排程流量 httpGet: port: 80 path:/index.html --- apiVersion: v1 kind: Service metadata: name: demo-service# service名稱 spec: selector:# 用於匹配後面POD物件 app: service ports: - protocol: TCP# 使用的協議 port: 80#service 埠號 targetPort: 80# 後端POD埠號 sessionAffinity: ClientIP#配置會話粘滯基於客戶端 sessionAffinityConfig:# 配置會話粘滯時間 clientIP: timeoutSeconds: 86400
部署
kubectl apply -f demo1.yaml
檢視後端POD情況

檢視serviceIP地址

測試

其實現了會話保持
3 服務發現
1 概述
由於各個服務之間需要能夠夠正常通訊並提供統一的穩定的訪問入口,所以POD客戶端中的應用需要知道某service資源的IP地址和埠號,這邊產生了service discovery
2 服務發現實現機制
1 部署穩定的服務註冊中心
2 服務提供者(POD及其應用)提供自己的位置資訊,並在變動後及時更新資訊
3 消費者(serice)週期性層註冊中心獲取服務者提供的最新資訊從而發現要訪問的目標服務欄位
3 服務發現型別
1 客戶端發現: 由客戶端到註冊中心發現其依賴到服務的相關資訊,其需要內建的發現程式和發現邏輯
2 服務端發現:需要使用中央路由器或服務均衡器的元件,服務消費者(客戶端 )將其請求傳送到中央路由器或負載均衡器,由他們負責查詢服務註冊中心獲取服務提供者的位置資訊,並將服務消費者的請求轉發給服務提供者(POD及其應用)
coreDNS
DNS是原始的服務發現系統之一,但其傳播速度過慢,後期常見的服務註冊中心是zookeeper 和 etcd 等分散式鍵值儲存系統,其只提供基本的資料儲存功能,距離實現完整的服務發現機制還有大量的開發任務,
Netflix 和 eureka 是目前較流行的服務發現系統之一,是專門開發用來實現服務發現的系統,以可用性目的為先,可以在多種故障期間保持服務發現和服務註冊功能的可用,
傳統DNS不適合微服務環境,但skyDNS實現了,
自K8S 1.3 開始,其服務發現的DNS 更新為了kubeDNS,而另一個較新的是 coreDNS,是基於GO語言開發,通過串接一組實現DNS功能的外掛的外掛連進行工作,自1.11開始coreDNS取代了kubeDNS成為預設的DNS附件。
4 服務發現
1 環境變數
建立POD資源時,kubelet會將其所屬名稱空間內的每個活動的service物件以一系列環境變數的形式注入其中,其支援使用kubernetes service環境變數以及與docker的links 相容的環境變數
1 kubernetes service 環境變數 kubernetes 為每個service資源生成包括下面形式的環境變數,在同一名稱空間(預設名稱空間default)中建立的POD物件自動擁有這些變數 .{SVCNAME}_SERVICE_HOST .{SVCNAME}_SERVICE_PORT 注意 : 如果SVCNAME 中使用了連結線,則kubernetes會在定義為環境變數時將其轉換為下劃線
2 docker link 形式的環境變數
Docker使用--link 選項實現容器連結時所設定的環境變數形式,在建立POD物件時,kubernetes會將與此形式相容的一系列環境變數注入POD物件中。
檢視之前建立的POD的環境變數
1 進入POD
kubectl exec -itservice-demo-7677648c64-m4nqh -- /bin/bash
檢視

其中DEMO_SERVICE 是之前建立的service的名稱,其以DEMO_SERVICE_SERVICE開頭的是kubernetes service資源的環境變數
基於環境變數的服務發現其功能簡單,已用,但存在侷限,僅有那些與建立POD物件在同一名稱空間中且實現存在的service物件的資訊才能以環境變數的形式入駐,那些處於非同一名稱空間或者在POD資源建立之後建立的service物件的相關環境變數則不會被新增。
2 cluster DNS
kubernetes上用於名稱解析和服務發現的clusterDNS 是叢集的核心附件之一,叢集中建立的每個service物件,都會有其自動生成相關資源記錄,預設情況,叢集中各POD物件會自動配置clusterDNS 作為其名稱解析伺服器,並在其DNS搜尋列表中包含其所屬的名稱空間的域名字尾。
不管是使用clusterDNS還是coreDNS,其提供的DNS的服務發現解決方案都會負責解析下面資源型別以實現服務發現。
1 擁有clusterIP的service資源,具有下面型別的資源記錄
A 記錄: <service>.<ns>.svc.<zone>.<ttl> IN A <cluster-ip>
SRV記錄: <port>. <proto>.<service>.<ns>.svc.<zone>.<ttl> IN SRV <weight> <priority><port-number><service>.<ns>.svc.<zone>
PTR記錄:<d>.<c>.<b><a>.in-addr.arpa.<ttl> IN PTR <service>.<ns>.svc.<zone>
2 headless 型別的service 資源
A 記錄 : <service>.<ns>.svc.<zone>.<ttl> IN A <endpoint-ip>
SRV 記錄 : <port>. <proto>.<service>.<ns>.svc.<zone>.<ttl> IN <weight><priority> <port-number> <hostname>.<ns>.svc.<zone>
PTR 記錄:<d>.<c>.<b>.<a>.in-addr-arpa.<ttl>IN PTR <hostname>.<service>.<ns>.svc.<zone>
3 externalName 型別資源的service資源,具有CNAME型別的資源記錄 。
CNAME 記錄: <service>.<ns>.svc.<zone>.<ttl> IN CNAME <extname>
名稱解析和服務發現是kubernetes系統需要功能得以實現的基礎服務,其通常是叢集安裝完成應該部署的附加元件,使用kubeadm 初始化一個叢集時,其會自動部署。
3 DNS
建立service資源物件時,clusterDNS 會自動建立資源記錄用於名稱解析和服務註冊。POD可直接使用其DNS 訪問service資源,每個service物件相關的DNS 記錄如下:
.{SVCNAME}.{NAMESPACE}.{CLUSTER_DOMAIN}
.{SVCNAME}.{NAMESPACE}.svc.{CLUSTER_DOMAIN}
--cluster-dns 指定了叢集DNS服務的工作地址
--cluster-domino 定義了叢集使用的本地域名。因此係統初始化預設會將"cluster.local."和主機所在的域"ilinux.io."作為DNS的本地域使用,這些資訊會在POD建立時以DNS配置的相關資訊注入它的/etc/resolv.conf 配置檔案中
檢視

{NAMESPACE}.svc.{CLUSTER_DEMAIN}: 如 default.svc.cluster.local svc.{CLUSTER_DOMAIN}: 如 svc.luster.local {CLUSTER_DOMAIN}: 如 cluster.local {WORK_NODE_DOMAIN}: 如上述未定義
4 服務暴露
預設的service 的IP預設是在叢集內部可達,但若需要外部訪問,則需要進行處理
1 service型別
1 clusterIP : 叢集內部可達,無法被外部客戶端訪問,建立service的預設訪問型別 2 NodePort:建立在clusterIP之上(叢集上的NODE節點+埠)均和訪問到。 3 loadbalancer:在NodePort之上,通過cloud provider提供的負載均衡器將服務暴露到叢集外部,因此loadbalancer具有NodePort和clusterIP。一個loadbalancer型別的service會指向關聯至kubernetes叢集外部的,切實存在的某個負載均衡裝置,該裝置通過工作節點上的NodePort 向叢集內部發送請求流量,其優勢在於能夠把來自叢集外部客戶端的請求排程至所有節點的NodePort 之上,而不是依賴於客戶端自動決定連結至那個節點,從而避免了因客戶端指定的節點故障而導致的服務不可用。 4 externalName: 通過將service對映到對映至由externalName欄位的內容指定的主機名來暴露服務,此主機名需要被DNS服務解析成CNAME 型別的記錄,其無clusterIP 和 Noport,也沒有標籤選擇器,因此沒endpoints ,其是一個域名,是CNAME結構,叢集內部的域名。
2 NodePort
1 概述
NodePort 及節點Port,其在安裝s集群系統時會預留一個埠範圍用於NodePort,預設是30000-32767之間的埠,ClusterIP型別可省略.spec.type,但其NodePort型別則必須指定對應的type方可。
2 刪除之前的例項 :
kubectl delete -f demo.yaml
修改結果如下
#root@master1 service]# cat demo.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: service-demo namespace: default spec: selector:#用於匹配後面POD物件 matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: service-demo image: nginx:1.14 ports:# 配置暴露埠 - name: http containerPort: 80 readinessProbe:#增加就緒性探測,用於探測服務是否正常執行,若未就緒則service不能向該POD上排程流量 httpGet: port: 80 path:/index.html --- apiVersion: v1 kind: Service metadata: name: demo-service# service名稱 spec: type: NodePort#指定其型別為NodePort selector:# 用於匹配後面POD物件 app: service ports: - protocol: TCP# 使用的協議 port: 80#service 埠號 targetPort: 80# 後端POD埠號 nodePort: 32380# 指定其節點埠為32380
此處可不配置nodePort,其會自動生成nodePort
3 部署
kubectl apply -f demo.yaml
檢視

其NodePort 資源會建立ClusterIP,事實上,其會作為節點從NodePort 接入流量後轉發至目標地址,目標埠則是與service資源對應的spec.ports.port屬性中定義的埠。
NodeIP:NodePort------> SrviceIP:ServicePort------>PodIP:PodPort
4 訪問測試
其內部可通過clusterIP進行訪問
3 loadBalancer
1 概述
NodePort 如果外部客戶端無法得知其IP地址和對應對映的埠,則其訪問不成功,其次,若對應IP地址的Node節點故障,則其訪問也將失敗,因此,一般還應在叢集外部建立一個具有公網IP地址的負載均衡器。由其接入外部客戶端請求並排程至叢集節點相應的NodePort之上。
相關例項如下:
2 刪除之前配置
kubectl delete -f demo.yaml
3 修改配置結果如下
[root@master1 service]# cat demo.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: service-demo namespace: default spec: selector:#用於匹配後面POD物件 matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: service-demo image: nginx:1.14 ports:# 配置暴露埠 - name: http containerPort: 80 readinessProbe:#增加就緒性探測,用於探測服務是否正常執行,若未就緒則service不能向該POD上排程流量 httpGet: port: 80 path:/index.html --- apiVersion: v1 kind: Service metadata: name: demo-service# service名稱 spec: type: LoadBalancer#指定其型別為LoadBalancer selector:# 用於匹配後面POD物件 app: service ports: - protocol: TCP# 使用的協議 port: 80#service 埠號 targetPort: 80# 後端POD埠號 nodePort: 32380# 指定其節點埠為32380
4 部署
kubectl apply -f demo.yaml
檢視

5 訪問測試
其可以使用NodePort的方式進行訪問

IaaS 雲端計算環境提供了LBaaS服務,它允許租戶動態的在自己的網路中建立一個負載均衡器,那些部署在此類環境上的kubernetes叢集在建立service資源時可以直接呼叫此介面按需建立一個軟負載均衡器,而具有這種功能的service資源及為loadBalancer型別,其目前環境不支援此種配置。
4 externalName
1 概述
externalName 型別的service資源用於將叢集外部的服務釋出到叢集中以供Pod中的應用程式訪問,因此,其不需要使用任何標籤選擇器關聯至任何POD物件,但必須要使用spec.externalName屬性定義一個CNAME記錄用於返回外部真正提供服務的主機別名,而後通過CNAME 記錄值獲取到相關主機的IP地址。
2 配置例項
例項如下:
#[root@master1 service]# cat ex.yaml apiVersion: v1 kind: Pod metadata: name: tomcat namespace: default labels: app: tomcat spec: containers: - name: tomcat image: tomcat:8.5.35 ports: - name: tomcat containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: external-tomcat-svc namespace: default spec: type: ExternalName externalName: www.baidu.com ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 0 selector: {}
3 部署服務
kubectl apply -f ex.yaml
檢視

等到此service資源 external-tomcat-svc 建立完成後,各POD物件即可通過external-tomcat-svc 或其FQDN格式的名稱 external-tomcat-svc.default.svc.cluster 訪問相應的資源,ClusterDNS 會將此名稱以CNAME 格式解析為.spec.externalName欄位中的名稱,而後通過DNS服務將其解析為相應的主機的IP地址.
4 測試 :
需要安裝nslookup 如下
#連結其中一個POD kubectl exec-it nginx-7bc476d88b-p5sv2-- /bin/bash 安裝nslookup apt-getupdate apt-get install dnsutils
檢視解析
解析到其name 為www.baidu.com
由於 externalName 型別的service資源實現於DNS級別,客戶端將其直接接入外部服務而完全不需要服務代理,因此,其無序配置clusterIP,此種類型也可稱為headless Service
5 headless
1 概述
service 物件隱藏了個POD資源,並負責將客戶端請求流量排程至POD上,但也有可能存在客戶端需要直接訪問service資源後端的所有POD資源,這時就應該向客戶端暴露每個POD資源的IP地址,而不是中間層service物件的ClusterIP,這種型別便是無頭服務。
headless service 物件沒有ClusterIP,因此便無相關負載均衡或代理問題,其如何為此類service配置IP地址,其取決於標籤選擇器的定義。 1 具有標籤選擇器 端點控制器(endpoints controller)會在API中為其建立endpoints記錄,並將clusterDNS服務中的A記錄直接解析到service後端的各個POD物件的IP地址上。 2 沒有標籤選擇器: 端點控制器(endpoints controller)不會在API中為其建立endpoints記錄,clusterDNS的配置分為兩種型別,對externalName的服務建立CNAME 記錄,對其他三種類型來說,為那些與當前service共享的名稱空間的所有endpoints物件建立一條記錄。
2 建立服務資源
例項
[root@master1 service]# cat demo.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: service-demo namespace: default spec: selector:#用於匹配後面POD物件 matchLabels: app: service template: metadata: labels: app: service spec: containers: - name: service-demo image: nginx:1.14 ports:# 配置暴露埠 - name: http containerPort: 80 readinessProbe:#增加就緒性探測,用於探測服務是否正常執行,若未就緒則service不能向該POD上排程流量 httpGet: port: 80 path:/index.html --- apiVersion: v1 kind: Service metadata: name: demo-service# service名稱 spec: clusterIP: None#指定其型別為Headless Service資源 selector:# 用於匹配後面POD物件 app: service ports: - protocol: TCP# 使用的協議 port: 80#定義暴露的埠 targetPort: 80# 後端POD埠號 name: httpport# 定義名字
部署服務
kubectl apply -f demo.yaml
檢視服務

其資源資訊中沒有ClusterIP,但其存在endpoints,
檢視其解析,其後端是POD的IP地址。其通過標籤選擇器選擇到此IP地址。於是客戶端向此service物件發起的請求將直接接入到POD資源中,而不再由service進行代理轉發。
檢視訪問資源

3 ingress資源應用
1 概述
kubernetes 提供了兩種內建的負載均衡機制,一種是位於傳輸層的TCP/IP service資源,其實現的是TCP負載均衡器,另一種是ingress資源,其實現的是HTTP(S)負載均衡器。 TCP負載均衡器 iptables 和 ipvs均實現的是四層排程,其不能基於URL 的請求排程機制,其也不支援為此類負載均衡配置任何型別的健康檢查機制。
2 ingress 和 ingress controller
ingress 是kubernetes API 的標準資源型別之一,其其實是一組基於DNS名稱或URL路徑把請求轉發至service資源的規則,用於將叢集外部的請求流量轉發至叢集內部完成服務釋出,ingress 資源自身並不能進行"流量穿透" ,其僅僅是一組路由規則的集合,這些規則要發揮相應的作用,則需要ingress controller,其可監聽套接字,然後給據這些規則的匹配機制路由請求流量。
注意 :ingress 不同於deployment,其不是直接執行與kube-controller-manager的一部分,其是kubernetes叢集的一個重要附件,需要單獨安裝才能使用。
ingress 控制器可以由任何具有反向代理(http/https)功能的伺服器程式實現,如nginx、envoy、haproxy、vulcand和traefik等,ingress控制器自身也是執行與叢集中的POD資源物件,其與北代理的執行的POD資源的應用運行於同一網路中。
另外: ingress控制器可基於ingress資源定義的規則將客戶端請求流量直接轉發到service對應的後端POD資源上,其會繞過service資源,省去了kube-proxy實現的埠代理開銷。
3 建立ingress資源
注:在此之前,需要先配置ingress資源控制器正常執行
如下

集體配置可參考 : https://blog.51cto.com/11233559/2364393 中的安裝和配置ingress服務
建立ingress資源
[root@master1 ingress]# cat demo.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: deploy-ingress namespace: default spec: selector: matchLabels: app: ingress template: metadata: namespace: default labels: app: ingress spec: containers: - name: pod-ingress image: nginx:1.14 ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: service-ingress namespace: default spec: selector: app: ingress ports: - protocol: TCP targetPort: 80 port: 80 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: demo-ingress annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: www.inginx.com#指定訪問使用的URL http: paths: - backend: serviceName: service-ingress#指定service的名稱 servicePort: 80#指定service的埠號
部署服務
kubectl apply -f demo.yaml
檢視服務

訪問檢視
相關欄位解析:
[root@master1 ingress]# kubectl explainingress.spec KIND:Ingress VERSION:extensions/v1beta1 RESOURCE: spec <Object> DESCRIPTION: Spec is the desired state of the Ingress. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status IngressSpec describes the Ingress the user wishes to exist. FIELDS: backend<Object>#預設的後端服務,用於哪些沒有匹配到任何規則的請求,定義ingress時,必須選擇backend或rules其中的一個。 A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default. rules<[]Object># 用於定義當前ingress欄位的轉發規則列表,未定義rules規則,或者沒有匹配到任何規則,所有流量都會轉發到由backend定義的預設後端。 A list of host rules used to configure the Ingress. If unspecified, or no rule matches, all traffic is sent to the default backend. tls<[]Object>#TLS 配置,目前僅支援通過預設埠443提供服務,如果要配置指定的列表成員指向了不同的主機,必須通過SBI TLS擴充套件機制來支援此功能。 TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI.
[root@master1 ingress]# kubectl explainingress.spec.backend KIND:Ingress VERSION:extensions/v1beta1 RESOURCE: backend <Object> DESCRIPTION: A default backend capable of servicing requests that don't match any rule. At least one of 'backend' or 'rules' must be specified. This field is optional to allow the loadbalancer controller or defaulting logic to specify a global default. IngressBackend describes all endpoints for a given service and port. FIELDS: serviceName<string> -required-#用於指定service名稱 Specifies the name of the referenced service. servicePort<string> -required-# 用於指定service埠 Specifies the port of the referenced service.
rules物件相關 spec: rules: - host:#指定訪問URL名稱 http: paths: - backend:#用於指定後端service資訊 serviceName: servicePort: path: #用於指定字尾
注意 :ingress.spec.rules.host 屬性值目前不支援使用IP地址,也不支援後跟":PORT"格式的埠號,且此欄位值留空表示通配所有的主機名。
[root@master1 ingress]# kubectl explainingress.spec.tls KIND:Ingress VERSION:extensions/v1beta1 RESOURCE: tls <[]Object> DESCRIPTION: TLS configuration. Currently the Ingress only supports a single TLS port, 443. If multiple members of this list specify different hosts, they will be multiplexed on the same port according to the hostname specified through the SNI TLS extension, if the ingress controller fulfilling the ingress supports SNI. IngressTLS describes the transport layer security associated with an Ingress. FIELDS: hosts<[]string># 包含與使用的TLS證書值內的主機名稱字串列表,因此,使用的主機名必須匹配tlsSecret 中的名稱 Hosts are a list of hosts included in the TLS certificate. The values in this list must match the name/s used in the tlsSecret. Defaults to the wildcard host setting for the loadbalancer controller fulfilling this Ingress, if left unspecified. secretName<string> # 用於引用SSL會話的secret物件名稱,在基於SNI實現多主機路由的場景中,此欄位為可選。 SecretName is the name of the secret used to terminate SSL traffic on 443. Field is left optional to allow SSL routing based on SNI hostname alone. If the SNI host in a listener conflicts with the "Host" header field used by an Ingre***ule, the SNI host is used for termination and value of the Host header is used for routing.
4 ingress資源型別
1 單個service資源型別
暴露單個服務的方法很多,如服務型別中的NodePort,loadBalancer等,方式旨在指定預設後端服務
#[root@master1 ingress]# cat nginx.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: default-backend-nginx namespace: default spec: backend: serviceName: nginx # 指定service名稱 servicePort: 80#指定service埠
檢視服務

2 基於URL路徑進行流量分發
[root@master1 ingress]# cat demo.yaml apiVersion: v1 kind: Pod metadata: name: nginx namespace: default labels: app: ingress spec: containers: - name: pod-ingress image: nginx:1.12 ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Pod metadata: name: tomcat namespace: default labels: app: ingress1 spec: containers: - name: pod-ingress1 image: tomcat:8.5.35 ports: - name: tomcat containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: service-ingress namespace: default spec: selector: app: ingress ports: - protocol: TCP targetPort: 80 port: 80 --- apiVersion: v1 kind: Service metadata: name: service-ingress1 namespace: default spec: selector: app: ingress1 ports: - protocol: TCP targetPort: 8080 port: 80 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: demo-ingress annotations: ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.inginx.com#指定訪問使用的URL http: paths: - path: /nginx backend: serviceName: service-ingress#指定service的名稱 servicePort: 80#指定service的埠號 - path: /tomcat backend: serviceName: service-ingress1 servicePort: 80
部署並檢視
kubectl apply -f demo.yaml
檢視

目前: ingress-nginx尚不能很好的支援此項功能,因此其目前不能使用
測試結果如下
可看到其配置檔案中版本號和測試結果版本號一致。
3 基於主機名稱的虛擬主機
1 去除上述配置
kubectl delete -f demo.yaml
配置相關服務
#[root@master1 ingress]# cat demo.yaml apiVersion: v1 kind: Pod metadata: name: nginx namespace: default labels: app: ingress spec: containers: - name: pod-ingress image: nginx:1.12 ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Pod metadata: name: tomcat namespace: default labels: app: ingress1 spec: containers: - name: pod-ingress1 image: tomcat:8.5.35 ports: - name: tomcat containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: service-ingress namespace: default spec: selector: app: ingress ports: - protocol: TCP targetPort: 80 port: 80 --- apiVersion: v1 kind: Service metadata: name: service-ingress1 namespace: default spec: selector: app: ingress1 ports: - protocol: TCP targetPort: 8080 port: 80 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: demo-ingress annotations: ingress.kubernetes.io/rewrite-target: / spec: rules: - host: www.inginx.com#指定訪問使用的URL http: paths: - path: backend: serviceName: service-ingress#指定service的名稱 servicePort: 80#指定service的埠號 - host: www.ttomcat.com http: paths: - path: backend: serviceName: service-ingress1 servicePort: 80
部署
kubectl apply -f demo.yaml
配置相關域名解析
測試


4 基於TLS 型別的ingress資源
這種型別用於以HTTPD釋出service資源,基於一個含有私鑰和證書的secret物件即可配置TLS協議的ingress資源,目前,ingress資源僅支援單TLS埠,並且還會解除安裝TLS會話,在ingress資源中引用此secret即可讓ingress控制器載入並配置HTTPS服務。
1 生成證書
openssl genrsa -out tls.key 2048 openssl req -new -x509 -key tls.key -out tls.crt -subj/C=CN/ST=shaanxi/L=xi\'an/O=linux/CN=www.inginx.io -days 3650
注: TLS secret中包含的證書必須以tls.crt作為其鍵名,私鑰檔案必須以tls.key作為鍵名。其CN=www.inginx.io 必須與後面對應的host相同
2 生成secret資源物件
kubectl create secret tls nginx-secret --cert=tls.crt --key=tls.key
檢視
3 部署配置
#[root@master1 ingress]# cat demo1.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-https-deploy namespace: default spec: selector: matchLabels: app: nginx-https template: metadata: namespace: default labels: app: nginx-https spec: containers: - name: nginx-https image: nginx:1.14 ports: - name: http containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: https-demo spec: selector: app: nginx-https ports: - port: 80 targetPort: 80 protocol: TCP --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: https-ingress namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - www.inginx.io#指定其訪問使用的域名 secretName: nginx-secret#指定其訪問時使用的證書 rules: - host: www.inginx.io http: paths: - path: / backend: serviceName: https-demo servicePort: 80
部署
kubectl apply -f demo1.yaml
配置相關解析
4 訪問檢視

證書資訊檢視
