NGINX Ingress controller can be installed via Helm using the chart from the project repository. To install the chart with the release name ingress-nginx
:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm install my-release ingress-nginx/ingress-nginx
通常情況下,service 和 pod 的 IP 僅可在集群內部訪問。集群外部的請求需要通過負載均衡轉發到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通過邊緣路由器 (edge router) 將其轉發給相關的 Pod 或者丟棄。如下圖所示
而 Ingress 就是為進入集群的請求提供路由規則的集合,如下圖所示

Ingress 可以給 service 提供集群外部訪問的 URL、負載均衡、SSL 終止、HTTP 路由等。為了配置這些 Ingress 規則,集群管理員需要部署一個 Ingress controller,它監聽 Ingress 和 service 的變化,並根據規則配置負載均衡並提供訪問入口。
#阿里雲稱之為ingress路由!在 Kubernetes 集群中,主要用於接入外部請求到k8s內部,Ingress是授權入站連接到達集群服務的規則集合,為您提供七層負載均衡能力。git地址:https://github.com/kubernetes/Ingress-nginx
Service缺點
#定義service以后,尤其是NodePort集群訪問,需要經過2級轉換調度,而且是4層調度,無論是iptables還是ipvs。4調度自身無法實現卸載https會話。
#ingress----k8s還有一種引入集群外部流量的方式,叫ingress。基於7層調度器。利用7層pod,將外部流量引入到內部。
Service 有四種類型:
-
ClusterIP:默認類型,自動分配一個僅 cluster 內部可以訪問的虛擬 IP
-
NodePort:在 ClusterIP 基礎上為 Service 在每台機器上綁定一個端口,這樣就可以通過
<NodeIP>:NodePort
來訪問該服務。如果 kube-proxy 設置了--nodeport-addresses=10.240.0.0/16
(v1.10 支持),那么僅該 NodePort 僅對設置在范圍內的 IP 有效。 -
LoadBalancer:在 NodePort 的基礎上,借助 cloud provider 創建一個外部的負載均衡器,並將請求轉發到
<NodeIP>:NodePort
-
ExternalName:將服務通過 DNS CNAME 記錄方式轉發到指定的域名(通過
spec.externlName
設定)。需要 kube-dns 版本在 1.7 以上。
Ingress支持的調度方式
1、url路徑映射調度: location /aa ; location /bb。可以參考nginx。
2、主機調度:l例如server aaa; server bbb
Ingress類型:1、url映射 2、虛擬主機
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: rules: - http: paths: - path: /testpath backend: serviceName: test servicePort: 80
每個 Ingress 都需要配置 rules
,目前 Kubernetes 僅支持 http 規則。上面的示例表示請求 /testpath
時轉發到服務 test
的 80 端口。
Kubernetes 版本 |
Extension 版本 |
v1.5-v1.17 |
extensions/v1beta1 |
v1.8+ |
networking.k8s.io/v1beta1 |
根據 Ingress Spec 配置的不同,Ingress 可以分為以下幾種類型:
單服務 Ingress 即該 Ingress 僅指定一個沒有任何規則的后端服務。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: backend: serviceName: testsvc servicePort: 80
注:單個服務還可以通過設置
Service.Type=NodePort
或者Service.Type=LoadBalancer
來對外暴露。
路由到多服務的 Ingress 即根據請求路徑的不同轉發到不同的后端服務上,比如
foo.bar.com -> 178.91.123.132 -> / foo s1:80 / bar s2:80
可以通過下面的 Ingress 來定義:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - path: /foo backend: serviceName: s1 servicePort: 80 - path: /bar backend: serviceName: s2 servicePort: 80
使用 kubectl create -f
創建完 ingress 后:
$ kubectl get ing NAME RULE BACKEND ADDRESS test - foo.bar.com /foo s1:80 /bar s2:80
虛擬主機 Ingress 即根據名字的不同轉發到不同的后端服務上,而他們共用同一個的 IP 地址,如下所示
foo.bar.com --| |-> foo.bar.com s1:80 | 178.91.123.132 | bar.foo.com --| |-> bar.foo.com s2:80
下面是一個基於 Host header 路由請求的 Ingress:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 - host: bar.foo.com http: paths: - backend: serviceName: s2 servicePort: 80
注:沒有定義規則的后端服務稱為默認后端服務,可以用來方便的處理 404 頁面。
TLS Ingress 通過 Secret 獲取 TLS 私鑰和證書 (名為 tls.crt
和 tls.key
),來執行 TLS 終止。如果 Ingress 中的 TLS 配置部分指定了不同的主機,則它們將根據通過 SNI TLS 擴展指定的主機名(假如 Ingress controller 支持 SNI)在多個相同端口上進行復用。
定義一個包含 tls.crt
和 tls.key
的 secret:
apiVersion: v1
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
kind: Secret
metadata:
name: testsecret
namespace: default
type: Opaque
Ingress 中引用 secret:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: no-rules-map spec: tls: - secretName: testsecret backend: serviceName: s1 servicePort: 80
注意,不同 Ingress controller 支持的 TLS 功能不盡相同。 請參閱有關 nginx,GCE 或任何其他 Ingress controller 的文檔,以了解 TLS 的支持情況。
可以通過 kubectl edit ing name
的方法來更新 ingress:
$ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 $ kubectl edit ing test
這會彈出一個包含已有 IngressSpec yaml 文件的編輯器,修改並保存就會將其更新到 kubernetes API server,進而觸發 Ingress Controller 重新配置負載均衡:
spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 path: /foo - host: bar.baz.com http: paths: - backend: serviceName: s2 servicePort: 80 path: /foo ..
更新后:
$ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 bar.baz.com /foo s2:80
當然,也可以通過 kubectl replace -f new-ingress.yaml
命令來更新,其中 new-ingress.yaml 是修改過的 Ingress yaml。
Ingress-controller:(提供特定功能的pod,nginx-ingress-controller-pod):提供接入外部流量的特定pod。例如有3個節點,在這3個節點打上污點,在每個上面運行特定的daemonset pod,實現外部流量接入,為后面pod提供7層調度。眾多控制器都是master節點的controllermanager的子件運行的。而ingree controller自己獨立運行,通常是一組pod資源。具有7層代理功能。
支持的代理工具:nginx、Traefik、Evoy(微服務)、HAproxy
watch:Service始終watch着后端pod變化。只要pod發生變化,api-server立刻檢測到。
Ingress
實現原理:
1、正常是用service去調度后面的適配label的pods,當pods增加,因為有labels,會自動識別后端添加的pods,如果用nginx怎么實現?把nginx運行在pod里面,配置文件在pod內部。這種pod叫ingress controller隨時觀察着后端的pod的改變。ingress controler自己沒有這種能力,借助於service去實現。所以nginx-ingress-controller后端還得建立service。這種service僅僅幫忙分類后端的pods資源。pods的配置在nignx里upstream面。service不會進行調度,僅僅分組。因此可以使用headless service,直接調度至后端pods。關鍵pods變化,怎么自動nginx的upstream以及其他配置,這種就通過ingress路由實現!
2、ingress需要建一個前端接入層,前端有可能是虛擬主機nginx配置的server,或者是location url映射,同時也要定義一個后端upstream-server。 upstream有幾個主機。通過service來獲取的。
3、ingress有個特點:作為資源來講,直接通過編輯注入到nginx-ingress-controller,並保存為nginx的配置文件。而且ingress一旦發現service 后端的pods改變,ingress直接注入更新nginx配置文件,而且需要重載配置文件(traefik支持自動重載)。
實現ingress步驟(7層調度):
1、第一步:部署一個nginx-ingress-controller-pod。部署一個特殊pod。
2、第二部:給nginx-ingress-controller-pod創建前端service1。用來接入外部請求!
3、創建nginx-ingress-controller-pod后端service2,以及service關聯的pods。
4、創建ingress、自動實現路由規則,自動實現service2自動注入到nginx-ingress-controller-pod規則(nginx.conf)
5、總結就是首先部署外部請求<------ingress-service<-----nginx-ingress-controller-pod<--------ingress<------service(headless、daemonset)<------pods
Ingress原理圖
原理:外部負載均衡器externalLB請求調至到 nodeport 里面service服務--->調度到內部pod(ingress controller里面)----->根據ingree定義,是虛擬主機,還是url代理---->假設是主機名,一組主機名對應后端的pod資源pod1,pod2,pod3。pod怎么分組通過service進行分組。才能被ingress引用。
先安裝ingress controller pod。然后定義ingress。再定義pod生成service。
動態生效:pod一變化,service就變化,service一變化,ingress就變化,ingreess一變化就注入到ingress controller里面。實時動態。
例子1(定義nginx-ingress-controller-pod) 3大步驟!
1、創建ingress-controller
#查看ingress幫助文檔
[root@node-001 ingress]# kubectl explain ingress.spec
#查看虛擬主機調度規則
[root@node-001 ingress]# kubectl explain ingress.spec.rules.host
#查看路徑url映射調度規則
[root@node-001 ingress]# kubectl explain ingress.spec.rules.http.paths
#查看路徑url映射調度規則
#查看url映射調用的后端主機規則(后端是通過service關聯一組后端pod)
[root@node-001 ingress]# kubectl explain ingress.spec.backend.servicename
#查看后端service后端的哪些pod,因為ingress backend后端就是根據service知道哪些pod資源。一旦pods變化,service就變化,service變化,ingress就變化,ingress一變化就注入到ingress-controller.
#tls字段: 配置ingress-controller虛擬機主機、或者url代理成https,需要用!!!!配置在ingress-controller相當於向后端代理時候,卸載了ssl會話。
######################################################################################################
原理注解:
把nginx作為ingress-controller-pod
github地址:https://github.com/kubernetes/ingress-nginx/
#第一步:創建名稱空間
#yum install git -y
https://github.com/kubernetes/ingress-nginx/blob/master/deploy/static/namespace.yaml
或者直接用命令創建:#kubectl create namespace dev #kubectl get namespace
#第二步:需要用到里面的configmap.yaml,存儲卷的時候后面講,主要用來從外部注入配置
#第三步:rbac.yaml 用來定義角色、授權。必要時讓ingress controller達到不了的名稱空間。用kube安裝的k8s默認啟用,必須要設置。
#第四步:接着設置with-rbac.yaml. 說明introller controller部署時候帶上rbac部署。
#第五步: 配置tcp-service-configmap.yaml。 新版本貌似沒有這個文件
[root@node-001 ingress-nginx]# git clone https://github.com/kubernetes/ingress-nginx.git
#把git文件先下載個備份保存一下。
######################################################################################################
下載nginx-ingress-controller相關的yaml清單(不行,手動下載)
[root@k8s-master ~]# mkdir ingress-nginx [root@k8s-master ~]# cd ingress-nginx/ [root@k8s-master ingress-nginx]# for file in namespace.yaml configmap.yaml rbac.yaml with-rbac.yaml ;do wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/$file;done
#會有幾個下載不了,有可能版本不匹配。注意這邊是raw格式的yaml所以下載地址不是github下載地址開頭的!
查看實際下載了哪些文件(一般下載4個即可)
[root@mater01 ingress]# ll
total 344
-rw-r--r-- 1 root root 75231 Jan 14 18:13 configmap.yaml
-rw-r--r-- 1 root root 70461 Jan 14 18:13 namespace.yaml
-rw-r--r-- 1 root root 103826 Jan 14 18:13 rbac.yaml
-rw-r--r-- 1 root root 90993 Jan 14 18:13 with-rbac.yaml
首先創建ingress-nginx名稱空間再批量其他yaml操作
[root@node-001 ingress-nginx]# kubectl apply -f namespace.yaml #會創建一個ingress-nginx名稱空間
namespace/ingress-nginx created
批量根據清單rbac等等(因為kubeadm安裝的k8s默認啟用了rbac)
[root@node-001 ingress-nginx]# kubectl apply -f ./
#直接apply當前目錄,全部自動創建。自動引入目錄下所有的yaml文件
#會自動下載nginx安裝pods
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
namespace/ingress-nginx unchanged
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
#查看自動安裝的nginx-ingress-controller-pod
[root@node-001 ingress-nginx]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 70s
#查看nginx-ingress-controller-pod是否成功
[root@node-001 ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 5d4h
#注意點:部署在裸機上面,需要額外加上service-Nodeport,雖然內部可以訪問,不然外網沒有介入。因為前面原理圖前面還需要加個service,當然第二種方式,ingress-controller設置為daemonset 設置hostnetwork字段共享節點網絡。
2、創建service和后端關聯的pods
首先部署后端的底層服務service以及pods
[root@node-001 ingress]# cd /opt/manifests/ingress/
[root@node-001 ingress]# vim deploy-demo.yaml #創建ingress---->后面service---->deployment(pods)
apiVersion: v1
kind: Service #給底層pod定義一個service。這個service必須為無頭服務,不然無法直接解析對應節點的ip地址。不然得到的是clusterip。往ingress-controller注入會有問題。奇怪的是這邊也可以。
metadata:
name: myapp
namespace: default
spec:
selector:
app: myapp
release: canary
ports:
- name: http
port: 80 #service啟動端口
targetPort: 80 #pod的端口
---
apiVersion: apps/v1 #上面一定要三個橫線分割!
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: http
containerPort: 80
查看后端pods、service、ingress-controller-pod
[root@node-001 manifests]# kubectl get pods -n ingress-nginx -w
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 3h12m
[root@node-001 ingress]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
myapp ClusterIP 10.111.24.58 <none> 80/TCP 101s #ingress后端的service已經創建成功(原理詳見上面的圖片!)
在指定名稱中,查看pods詳細信息
[root@node-001 manifests]# kubectl describe pods nginx-ingress-controller-568867bf56-q2pt2 -n ingress-nginx
小知識:不想一個個創建pods、service、ingress-contoller怎么辦?直接用官網的mandatory.yaml直接安裝
https://github.com/kubernetes/ingress-nginx/blob/master/deploy/static/mandatory.yaml
3、創建nginx-ingress-controller-pod前面一層service(不然ingrss-controller沒法接入外部請求流量)
核心原理:就是把nginx-ingress-controller-pod,這個特殊pod前面再定義一個service,例如前后端分離,前端接口直接調用這個service實現后端接口訪問,這步驟很關鍵!
#部署Service:ingress-controller(nginx)前端的service,確保外部可以訪問
下載清單文件
手動創建ning-ingree-service清單(不能下載的話)!並修改一下!(創建ingress-nginx前面的service)
#vim service-nodeport.yaml
[root@mater01 ingress]# cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: NodePort #service-ingree類型為NodePort
ports:
- name: http
port: 80 #定義nginx-ingress-controller-pod前面的service端口是80
targetPort: 80 #nginx-ingress-pod端口
protocol: TCP
nodePort: 30080 #指定serice-ingress端口300080,不然隨機分配!注意這個service端口會在k8s所有集群機器開啟!
- name: https
port: 443 #service端口是443
targetPort: 443 #pod端口,但是這邊沒有指定節點端口,所以service節點端口隨機分配30000~32767?
protocol: TCP
nodePort: 30443 #指定service端口30443不然隨機分配!注意這個service端口會在k8s所有集群機器開啟!
selector:
app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx
#注意這個selector特別重要!不然創建的這個service無法把前面創建的ingress-nginx-pod匹配做為endpoints!怎么寫(describe pod看一下)看下面!
查看selector怎么寫?查看ingress-nginx這個pod是否正常運行!
[root@mater01 ingress]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-948ffd8cc-jqp2h 1/1 Running 0 4h8m
查看ingress-nginx-pod的詳細信息
[root@mater01 ingress]# kubectl describe pod nginx-ingress-controller-948ffd8cc-jqp2h -n ingress-nginx
Name: nginx-ingress-controller-948ffd8cc-jqp2h
Namespace: ingress-nginx
Priority: 0
Node: node02/172.19.72.234
Start Time: Wed, 15 Jan 2020 10:46:09 +0800
Labels: app.kubernetes.io/name=ingress-nginx #這邊是ingress-ninx的pod的標簽信息,把這個信息寫到前面創建service的slector清單里面去!這步驟很重要!否則創建的service-ingress-nginx無法匹配到ingress-nginx-pod!
app.kubernetes.io/part-of=ingress-nginx
pod-template-hash=948ffd8cc
查看創建的ingress-nginx前面的service服務
[root@mater01 ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.101.71.230 <none> 80:30080/TCP,443:30443/TCP 2m23s
#這邊可以看到service類型為nodeport。端口容器內端口80映射主機端口為30080和30443端口
查看ingress-nginx前面的service是否正常,以及這個service是否匹配到后端的ingress-nginx-pod!
[root@mater01 ingress]# kubectl describe svc ingress-nginx -n ingress-nginx
Name: ingress-nginx
Namespace: ingress-nginx
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"ingress-nginx","namespace":"ingress-nginx"},"spec":{"ports":[{"na...
Selector: app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
Type: NodePort
IP: 10.103.42.166
Port: http 80/TCP
TargetPort: 80/TCP
NodePort: http 30080/TCP
Endpoints: 10.244.2.6:80 #這邊可以看到service成功匹配到后端的ingress-nginx的pod!
Port: https 443/TCP
TargetPort: 443/TCP
NodePort: https 30443/TCP
Endpoints: 10.244.2.6:443
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
查看狀態
[root@node-001 ~]# kubectl get pods -o wide --show-labels -n ingress-nginx
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
nginx-ingress-controller-568867bf56-q2pt2 1/1 Running 0 5d4h 10.244.1.91 node-002 <none> <none> app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=568867bf56
查看service-ingress-nginx
[root@node-001 ingress]# kubectl get svc -n ingress-nginx
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx ingress-nginx NodePort 10.103.231.49 <none> 80:30080/TCP,443:30443/TCP 48s
#30080端口是service-ingress-nginx的端口,因為前面創建service-ingress-nginx指定service類型為NodePort,端口指定為30080 30443。注意這個端口只要是servic端口!會在集群所有機器開啟。
[root@node-001 ingress]# netstat -tunlp|grep 30080
tcp6 0 0 :::30080 :::* LISTEN 3329/kube-proxy
[root@node-001 ingress]# netstat -tunlp|grep 30443
tcp6 0 0 :::30443 :::* LISTEN 3329/kube-proxy
在外部IE瀏覽器嘗試訪問service-ingress-nginx
訪問方式:IP:30080 IP:30443
此時應該是404 ,調度器是正常工作的,但是后端服務沒有關聯
谷歌瀏覽器訪問: 192.168.100.180:30080
default backend -404 #因為沒有定義規則,后端調度沒有配置!所以是失敗的。
實驗到此總結:第一步創建nginx-ingress-controller-pod、第二步創建nginx-ingress-controller-pod前面的service-ingress-nginx,指定service類型為Nodeport類型。第三步創建底層deploument-pods、第四步配置ingress路由規則全部打通!
4、配置ingress路由規則導入。
創建ingress清單
#用ingress自動把pods轉換為nginx的配置文件(例如加到upstream里面)。
#核心:利用注解信息annotations標注用的是nginx作為ingress-controller,因為除了nginx還有envoy、traefic等!
--------------------------------------------------------------------------------
[root@mater01 ingress]# kubectl explain ingress #查看定義幫助文檔!不會的話百度!!
[root@k8s-master ingress]# vim ingress-myapp.yaml
apiVersion: extensions/v1beta1 #api版本
kind: Ingress #清單類型
metadata: #元數據
name: ingress-myapp #定義ingress的名稱
namespace: default #定義ingress路由所屬名稱空間,注意要和deployment和要發布的service一個名稱空間!
annotations: #標注我們用的是nginx,不是envoy、traefic等,核心代碼。
kubernetes.io/ingress.class: "nginx" #這個很重要!核心配置,表示前面用的ingress-controller是nginx!才能生成規則!#kubernetes.io是前綴 ingress.class是鍵名 nginx是數值。表示我們用的ingress-controller是nginx,這樣才能自動生成nginx規則!
spec: #下面定義規則!
rules: #定義后端轉發的規則。# kubectl explain ingress.spec
- host: myapp.dayu.com 使用第一種,虛擬主機來做!nginx有兩種一種是虛擬主機,一種是URL映射!通過域名進行轉發#需要確保,在互聯網外部能解析這個主機名字!解析的結果能達到前面的nodeport-service。
http: #利用http定義前后端路徑!
paths: #查看幫助文檔:# kubectl explain ingress.spec.rules.http.paths
- path: #配置域名訪問路徑,如果通過url進行轉發,需要修改;空默認為訪問的路徑為"/"
backend: #指定后端服務。
serviceName: myapp #ingress后端的service名字!
servicePort: 80 #ingress-后端service的端口是80 # kubectl describe svc myapp,Endpoints: 10.244.1.10:80,10.244.1.9:80,10.244.2.9:80 這個三個pod作為upstream的后端!
創建ingress路由
[root@k8s-master ingress]# kubectl apply -f ingress-myapp.yaml
[root@k8s-master ingress]# kubectl get ingress
#查看ingress服務 NAME HOSTS ADDRESS PORTS AGE ingress-myapp myapp.dayu.com 80 46s
查看ingress信息
[root@node-001 ingress]# kubectl get ingress -A
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
default ingress-myapp myapp.dayu.com 10.103.231.49 80 16m
[root@node-001 ingress]# kubectl describe ingress ingress-myapp
Name: ingress-myapp
Namespace: default
Address: 10.103.231.49
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
myapp.dayu.com #主機名
myapp:80 (10.244.1.95:80,10.244.1.96:80,10.244.1.97:80) #后端提供pod服務地址!
Annotations:
kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"ingress-myapp","namespace":"default"},"spec":{"rules":[{"host":"myapp.dayu.com","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":null}]}}]}}
kubernetes.io/ingress.class: nginx #ingress前面的類別用的是nginx,不是envoy、traefic!
#(ingress路由創建完成,會自動配置ingress-nginx配置文件)
#進入ingress-controller-pod的nginx,查看nginx配置文件
[root@mater01 ingress]# kubectl get pods -A|grep ingress-nginx
ingress-nginx nginx-ingress-controller-948ffd8cc-jqp2h 1/1 Running 0 2d
[root@node-001 ingress]# kubectl exec -n ingress-nginx -it nginx-ingress-controller-568867bf56-q2pt2 -- /bin/sh
$ ls
fastcgi_params mime.types nginx.conf template
geoip modsecurity opentracing.json
lua modules owasp-modsecurity-crs
$ cat nginx.conf
xxxx 這個nginx配置文件
修改linux主機、以及windows主機hosts
[root@mater01 ~]# vim /etc/hosts
192.168.100.180 myapp.dayu.com
192.168.100.181 myapp.dayu.com
瀏覽器chrome瀏覽器輸入:myapp.dayu.com:30080 或者http://myapp.dayu.com:30080/hostname.html
實驗到此成功結束!
例子2(實戰tomcat)
每個node拉取鏡像
[root@node-001 ingress]# docker pull tomcat:8.5.34-jre8-alpine
#去dockerhub.com下載容器:hub.docker.com
創建Service和Pod配置文件
[root@node-001 ingress]# vim tomcat-deploy.yaml
apiVersion: v1
kind: Service #這個service必須為無頭服務,不然無法解析對應節點的ip地址。
metadata:
name: tomcat
namespace: default
spec:
selector:
app: tomcat
release: canary
ports:
- name: http
port: 8080 #這邊是service的8080端口映射后端tomcat-pod的8080,但是這個是service層面的,只是cluster ip層級的。用來被ingress規則所識別有哪些后端pod,哪些端口。
targetPort: 8080
- name: ajp
port: 8009
targetPort: 8009
---
apiVersion: apps/v1 #--- 三個橫線表示分割
kind: Deployment
metadata:
name: tomcat-deploy
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: tomcat
release: canary
template:
metadata:
labels:
app: tomcat
release: canary
spec:
containers:
- name: tomcat
image: tomcat:8.5.34-jre8-alpine
ports:
- name: http
containerPort: 8080
- name: ajp
containerPort: 8009
創建Pods以及Service
[root@node-001 ingress]# kubectl apply -f tomcat-deploy.yaml
service/tomcat created
檢查tomcat是否跑在8080端口
[root@node-001 ingress]# kubectl exec -it tomcat-deploy-56c494fc77-cm6f5 -- /bin/sh
[root@node-001 ingress]# kubectl exec -it tomcat-deploy-56c494fc77-cm6f5 -- netstat -tunlp
/usr/local/tomcat # netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::8080 :::* LISTEN 1/java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 1/java
tcp 0 0 :::8009
創建ingress路由規則(基於域名)
[root@node-001 ingress]# vim ingress-tomcat.yaml
apiVersion: extensions/v1beta1 #ingress-api版本 #kubcectl explian ingress
kind: Ingress #清單類型是ingress路由
metadata:
name: ingress-tomcat #ingress路由的名稱
namespace: default #所屬名稱空間,要和后端發布的service屬於同一名稱之中。
annotations: #注解信息,說明下面用到的是nginx不是其他的才能轉換為ingress-contorller規則
kubernetes.io/ingress.class: "nginx" #說明ingress-controller用的是nginx,這樣才能生成匹配規則。
spec: #定義ingress規則
rules: #定義后端轉發的規則
- host: tomcat.dayu.com #通過域名進行轉發
http:
paths:
- path: #配置訪問路徑,如果通過url進行轉發,需要修改;空默認為訪問的路徑為"/"
backend: #配置ingress后端的service服務
serviceName: tomcat #后端service暴露的名字,ingress通過這個service去關聯后端pods。
servicePort: 8080 #后端service端口!ingree默認是80.怎么再暴露一個8009,再定義一個path。也就是說 訪問nginx 的80。 nginx反向代理到service的8080端口。
創建ingress規則
[root@node-001 ingress]# kubectl apply -f ingress-tomcat.yaml
ingress.extensions/ingress-myapp configured
[root@node-001 ingress]#
[root@node-001 ingress]# kubectl get ingress -A
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
default ingress-myapp tomcat.dayu.com 80 7s
[root@node-001 ingress]# kubectl describe -n default ingress ingress-tomcatp
查看路由規則
[root@mater01 ingress]# kubectl get ingress -A
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
default ingress-myapp myapp.dayu.com 10.103.42.166 80 20m
k8s節點所有linux主機添加hosts解析
[root@mater01 ~]# vim /etc/hosts
192.168.100.180 tomcat.dayu.com
192.168.100.181 tomcat.dayu.com
本地windows電腦添加hosts添加解析
192.168.100.180 myapp.dayu.com tomcat.dayu.com
windows打開瀏覽器輸入C:\windows\System32\drivers\etc
tomcat.dayu.com:30080 #nginx服務暴露的端口
或者直接在linux機器執行
[root@mater01~]# curl tomcat.dayu.com:30080
[root@mater01~]# curl tomcat.dayu.com:30443
#因為創建ingress-nginx-service暴露的是30080端口!
[root@mater01 ingress]# kubectl get svc -A|grep ingress-nginx
ingress-nginx ingress-nginx NodePort 10.103.42.166 <none> 80:30080/TCP,443:30443/TCP 44h
可以登錄nginx-pod查看ngin-conf生成的規則,只要ingress已創建,直接映射進去了。
例子3(實戰tomcat配置https證書)
#創建 自簽證書,然后把證書轉換為secreat,加載到pod里面去!
創建證書
[root@node-001 ingress]# openssl genrsa -out tls.key 2048
Generating RSA private key, 2048 bit long modulus
................+++
..+++
e is 65537 (0x10001)
[root@node-001 ingress]# ls
deploy-demo.yaml ingress-myapp.yaml ingress-nginx ingress-tomcat.yaml service-nodeport.yaml tls.key tomcat-demo.yaml tomcat-pod.yaml
[root@node-001 ingress]#
[root@node-001 ingress]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.dayu.com
[root@node-001 ingress]# ls
deploy-demo.yaml ingress-myapp.yaml ingress-nginx ingress-tomcat.yaml service-nodeport.yaml tls.crt tls.key tomcat-demo.yaml tomcat-pod.yaml
[root@node-001 ingress]#
#注意證書不能直接貼到nginx里面。需要轉換成特殊格式。secreat,screat可以注入到k8s,被k8s引用。
[root@node-001 ingress]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
secret/tomcat-ingress-secret created
查看目前的secret
[root@node-001 ingress]# kubectl get secret
NAME TYPE DATA AGE
default-token-xd2gw kubernetes.io/service-account-token 3 26d
tomcat-ingress-secret kubernetes.io/tls 2 18s #已經被創建。
查看tomcat的secret
[root@node-001 ingress]# kubectl describe secret tomcat-ingress-secret
Name: tomcat-ingress-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.key: 1679 bytes
tls.crt: 1289 bytes
[root@node-001 ingress]#
把tls配置進去
[root@node-001 ingress]# kubectl explain ingress.spec.tls
[root@node-001 ingress]# cp ingress-tomcat.yaml ingress-tomcat-tls.yaml
[root@node-001 ingress]# vim ingress-tomcat-tls.yaml
apiVersion: extensions/v1beta1 #api版本
kind: Ingress #清單類型
metadata: #元數據
name: ingress-tomcat-tls #ingress的名稱
namespace: default #所屬名稱空間,和要發布的service屬於同一名稱之中。
annotations: #注解信息,說明下面用到的是nginx不是其他的。才能轉換為ingress-contorller對應匹配的規則
kubernetes.io/ingress.class: "nginx" #說明ingress-controller用的是nginx,這樣才能生成匹配規則。
spec: #規格
tls:
- hosts:
- tomcat.dayu.com #把哪個主機做成tls。
secretName: tomcat-ingress-secret #通過命令查看: kubectl get secret
rules: #定義后端轉發的規則
- host: tomcat.dayu.com #通過域名進行轉發
http:
paths:
- path: #配置訪問路徑,如果通過url進行轉發,需要修改;空默認為訪問的路徑為"/"
backend: #配置后端服務
serviceName: tomcat #后端service暴露的名字
servicePort: 8080 #后端service端口
應用tls
[root@node-001 ingress]# kubectl apply -f ingress-tomcat-tls.yaml
ingress.extensions/ingress-tomcat-tls created
查看ingress詳細
[root@node-001 ingress]# kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-tomcat tomcat.dayu.com 10.103.231.49 80 80m
ingress-tomcat-tls tomcat.dayu.com 10.103.231.49 80, 443 40s
[root@node-001 ingress]# kubectl describe ingress
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 53s nginx-ingress-controller Ingress default/ingress-tomcat-tls
Normal UPDATE 49s nginx-ingress-controller Ingress default/ingress-tomcat-tls
進入ingress-nginx命名空間的pod,查看
[root@node-001 ingress]# kubectl exec -it -n ingress-nginx nginx-ingress-controller-568867bf56-q2pt2 -- /bin/sh
$ ls
fastcgi_params geoip lua mime.types modsecurity modules nginx.conf opentracing.json owasp-modsecurity-crs template
$ cat nginx.conf
xxxxxx
server {
server_name tomcat.dayu.com ;
listen 80 ;
listen [::]:80 ;
listen 443 ssl http2 ;
listen [::]:443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
# PEM sha: c8b9956633fbec541a874a74ff309f8477b4d0f4
ssl_certificate /etc/ingress-controller/ssl/default-fake-certificate.pem;
ssl_certificate_key /etc/ingress-controller/ssl/default-fake-certificate.pem;
xxxxxx
打開瀏覽器訪問試下
https://tomcat.dayu.com:30443/ nginx映射的端口
igress實驗到此結束!
[root@master ~]# cat mandatory.yaml apiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: name: nginx-ingress-serviceaccount namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: nginx-ingress-role namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - pods - secrets - namespaces verbs: - get - apiGroups: - "" resources: - configmaps resourceNames: - "ingress-controller-leader-nginx" verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: nginx-ingress-role-nisa-binding namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-role subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: nginx-ingress-clusterrole-nisa-binding labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop: exec: command: - /wait-shutdown --- apiVersion: v1 kind: LimitRange metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: limits: - min: memory: 90Mi cpu: 100m type: Container
[root@master ~]# kubectl apply -f https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yamlerror: error parsing https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml: error converting YAML to JSON: yaml: line 124: mapping values are not allowed in this context[root@master ~]# wget https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml--2020-08-19 13:55:58-- https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yamlResolving github.com (github.com)... 13.229.188.59Connecting to github.com (github.com)|13.229.188.59|:443... connected.HTTP request sent, awaiting response... 200 OKLength: unspecified [text/html]Saving to: ‘mandatory.yaml’
[ <=> ] 156,495 175KB/s in 0.9s
2020-08-19 13:56:03 (175 KB/s) - ‘mandatory.yaml’ saved [156495]
[root@master ~]#