k8s——ingress


目錄

一、Ingress簡介

1.1 service的作用

1.對集群內部,它不斷跟蹤pod的變化,更新endpoint中對應pod的對象,提供了ip不斷變化的pod的服務發現機制
2.對集群外部,他類似負載均衡器,可以在集群內外部對pod進行訪問

1.2 外部訪問k8s集群內的服務

1.NodePort:測試環境使用還行,當有幾十上百的服務在集群中運行時,NodePort的端口管理就是個災難
2.LoadBalancer:受限於雲平台,且通常在雲平台部署LoadBalancer還需要額外的費用
3.Ingress:可以簡單理解為service的service,它其實就是一組基於域名和URL路徑,把用戶的請求轉發到一個或多個service的規則

二、Ingress組成

2.1 ingress

1.ingress是一個APr對象,通過yaml文件來配置,ingress對象的作用是定義請求如何轉發到service的規則,可以理解為配置模板
2.ingress通過http或https暴露集群內部service,給service提供外部URL、負載均衡、SSL/TLs能力以及基於域名的反向代理。ingress要依靠ingress-controller來具體實現以上功能

2.2 ingress-controller

1.ingress-controller是具體實現反向代理及負載均衡的程序,對ingress定義的規則進行解析,根據配置的規則來實現請求轉發
2.ingress -controller並不是kes自帶的組件,實際上ingress-controller只是一個統稱,用戶可以選擇不同的ingress-controller實現,目前,由k8s維護的ingress-controller只有google雲的ccz與ingress-nginx兩個,其他還有很多第三方維護的ingres-controller,具體可以參考官方文檔。但是不管哪一種ingress-controller,實現的機制都大同小異,只是在具體配置上有差異
3.一般來說,ingress-controller的形式都是一個pod,里面跑着daemon程序和反向代理程序。daemcn負責不斷監控集群的變化,根據ingress對象生成配置並應用新配置到反向代理,比如ingress -nginx就是動態生成nginx配置,動態更新upstrea,並在需要的時候reloada程序應用新配置。為了方便,后面的例子都以k8s官方維護的ingress-nginx為例
4.Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx官方網站:https:/kubernetes.github.io/ingress-nginx/
5.總結: ingress-controller才是負責具體轉發的組件,通過各種方式將它暴露在集群入口,外部對集群的請求流量會先到

三、Ingress工作原理

1.ingress-controller通過和 kubernetes APIServer 交互,動態的去感知集群中ingress規則變化
2.然后讀取它,按照自定義的規則,規則就是寫明了哪個域名對應哪個service,生成一段nginx配置
3.再寫到nginx-ingress-controller的pod里,這個ingress-controller的pod里運行着一個nginx服務,控制器會把生成的nginx配置寫入/etc/nginx.conf文件中
4.然后reload一下使配置生效。以此達到域名區分配置和動態更新的作用

四、部署nginx-ingress-controller

4.1 部署ingress-controller pod及相關資源

1.mkdir /opt/ingress
2.cd /opt/ingress
==========================================================
官方下載地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml

上面可能無法下載,可用國內的gitee
3.wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml

wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml

#mandatory.yaml文件中包含了很多資源的創建,包括namespace、configMap、role,ServiceAccount等等所有部署ingress-controller需要的資源

4.2 修改clusterRole資源配置

vim mandatory.yaml
....
- apiGroups:
    - ""
  resources:
    -services
  verbs:
    - get
    - list
    - watch
- apiGroups:
    - "extensions"
    - "networking.k8s.io"#增加(0.25版本)
  resources:
    - ingresses
  verbs:
    - get
    - list
    - watch
- apiGroups:
    - ""
  resources:
    - events
  verbs:
    - create
    - patch
- apiGroups:
    - "extensions"
    - "networking.k8s.io"#增加(o.25版本)
  resources:
    - ingresses/ status
  verbs:
    - update

五、ingress暴露服務的方式

1.Deployment+LoadBalancer模式的Service

如果要把ingress部署在公有雲,那用這種方式比較合適。用Deployment部署ingress-controller,創建一個type為 LoadBalancer的 service關聯這組pod。大部分公有雲,都會為 LoadBalancer的 service自動創建一個負載均衡器,通常還綁定了公網地址。只要把域名解析指向該地址,就實現了集群服務的對外暴露

2.DaemonSet+HostNetwork+nodeselector

用DaemonSet結合nodeselector來部署ingress-controller到特定的node 上,然后使用Hostiletwork直接把該pod與宿主機node的網絡打通,直接使用宿主機的80/433端口就能訪問服務。這時,ingress-controller所在的node機器就很類似傳統架構的邊緣節點,比如機房入口的nginx服務器。該方式整個請求鏈路最簡單,性能相對NodePort模式更好。缺點是由於直接利用宿主機節點的網絡和端口,一個node只能部署一個ingress-controller pod。比較適合大並發的生產環境使用

3.Deployment+NodePort模式的Service

1)同樣用deployment模式部署ingres-controller,並創建對應的服務,但是type為NodePort。這樣,ingress就會暴露在集群節點ip的特定端口上
2)由於nodeport暴露的端口是隨機端口,一般會在前面再搭建一套負載均衡器來轉發請求。該方式一般用於宿主機是相對固定的環境ip地址不變的場景
3)NodePort方式暴露ingress雖然簡單方便,但是NodePort多了一層NAT,在請求量級很大時可能對性能會有一定影響

六、采用方式二:DaemonSet+HostNetwork+nodeselector

6.1 指定nginx-ingress-controller運行在node02節點

kubectl label node node02 ingress=true

kubectl get nodes --show-labels

6.2 修改Deployment為Daemonset,指定節點運行,並開啟 hostNetwork

vim mandatory.yaml
...
apiversion: apps/vl
kind: Daemonset   #修改kind
...
hostNetwork: true  #使用主機網絡
nodeSelector:
  ingress: "true"   #選擇節點運行
...


6.3 所有node節點上傳nginx-ingress-controller鏡像壓縮包ingree.contro.tar.gz.到/opt/ingress目錄,並解壓和加載鏡像

mkdir /opt/ingress
cd /opt/ingress
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar

6.4 啟動nginx-ingress-controller

#主節點
kubectl apply -f mandatory.yaml

kubectl get pod -n ingress-nginx -o wide

到node02節點查看
netstat -natp | grep nginx
==========================================================
由於配置了hostnetwork, nginx已經在 node主機本地監聽團/443/8181端口。其中 8181 是nginx-controller默認配置的一個defaultbackend (Ingress資源沒有匹配的 rule 對象時,流量就會被導向這個default backend)
這樣,只要訪問 node主機有公網 TP,就可以直接映射域名來對外網暴露服務了。如果要nginx高可用的話,可以在多個node39上部署,並在前面再搭建一套LVS+keepalive做負載均衡。

6.5 創建ingress規則

6.5.1 創建一個deployment和svc

在主節點創建
vim service-nginx.yaml
==========================================================
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: nginx-app
  name: nginx-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx-app
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata :
  name: nginx-service
spec:
  type: ClusterIP
  ports :
  - port: 7777
    targetPort: 80
  selector :
   app: nginx
==========================================================
kubectl apply -f service-nginx.yaml

kubectl get pod,svc

6.5.2 創建ingress

vim ingress-1.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: www.gxd.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service  #指定你創建的svc的名稱
          servicePort: 80
==========================================================
kubectl apply -f ingress-1.yaml

kubectl get pod,svc,ingress

6.6 做端口映射並訪問測試

echo '192.168.10.30 www.gxd.com' >> /etc/hosts

curl www.gxd.com

6.7 查看nginx-ingress-controller

kubectl get pod -n ingress-nginx -o wide

kubectl exec -it nginx-ingress-controller-k5vvf  -n ingress-nginx bash



七、采用方式三:Deployment+NodePort模式的Service

7.1 下載nginx-ingress-controller和ingress-nginx暴露端口配置文件

在主節點
mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport

官方下載地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

國內 gitee 資源地址:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

7.2 在所有node節點上傳鏡像包ingress-controller-0.30.0.tar到/opt/ingress-nodeport目錄,並加載鏡像

在所有node節點
mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport
tar zxvf ingree.contro-0.30.0.tar.gz
docker load -i ingree.contro-0.30.0.tar

7.3 啟動nginx-ingress-controller

kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml

7.4 創建deployment、service和ingress的yaml資源

vim ingress-nginx.yaml 
==========================================================
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
spec:
  rules:
    - host: www.gxd111.com
      http:
        paths:
        - path: /
          backend:
            serviceName: nginx-svc
            servicePort: 80
==========================================================kubectl apply -f ingress-nginx.yaml                       
kubectl get pod,svc,ingress -owide

7.5 做端口映射並訪問測試

echo '192.168.10.30 www.gxd111.com' >> /etc/hosts

curl www.gxd111.com

八、ingress http代理訪問虛擬主機

mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
==========================================================
#創建虛擬主機1資源
vim demo1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment1
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx1
    spec:
      containers:
        - name: nginx1
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    name: nginx1
  type: ClusterIP
==========================================================
#創建虛擬主機2資源
vim demo2.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx2
    spec:
      containers:
        - name: nginx2
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-2
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    name: nginx2
  type: ClusterIP
==========================================================
創建ingress資源
vim ingress-nginx.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress1
spec:
  rules:
    - host: www1.gxd.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-1
            servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress2
spec:
  rules:
    - host: www2.gxd.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-2
            servicePort: 80
==========================================================
kubectl apply -f demo1.yaml
kubectl apply -f demo2.yaml
kubectl apply -f ingress-nginx.yaml
kubectl get pod,svc,ingress

echo '192.168.10.30 www1.gxd.com ' >> /etc/hosts
echo '192.168.10.30 www2.gxd.com ' >> /etc/hosts
curl www1.gxd.com:31396
curl www2.gxd.com:31396

九、ingress https代理訪問

9.1 創建工作目錄

mkdir /opt/ingress-nodeport/https
cd /opt/ingress-nodeport/https

9.2 創建ssl證書

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj  "/CN=nginXsvc/O=nginxsvc"

9.3 創建secret資源進行存儲

kubectl create secret tls tls-secret --key tls.key --cert tls.crt

kubectl get secret

kubectl describe secret tls-secret

9.4 創建deployment、service和ingress的yaml資源

vim demo3.yaml 
==========================================================
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress3
spec:
  tls:
    - hosts: 
      - www.gxd222.com
      secretName: tls-secret
  rules: 
    - host: www.gxd222.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-3
            servicePort: 80
==========================================================kubectl apply -f demo3.yaml                       
kubectl get pod,svc,ingress 

9.5 做端口映射並訪問測試

echo '192.168.10.30 www.gxd222.com' >> /etc/hosts

在瀏覽器訪問 https://www.gxd222.com:31067
點擊高級選項,確認安全例外即可

十、nginx進行BasicAuth(訪問前輸入用戶和密碼)

10.1 創建工作目錄

mkdir /opt/ingress-nodeport/basic-auth
cd /opt/ingress-nodeport/basic-auth

10.2 生成用戶密碼文件,創建secret資源進行存儲

yum install -y httpd
htpasswd -c auth gxd
kubectl create secret generic basic-auth --from-file=auth
kubectl get secret
kubectl describe secret basic-auth

10.3 創建ingress資源

//具體詳細設置方法可參考官網https://kubernetes.github.io/ingress-nginx/examples/auth/basic/

vim ingress-auth.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-auth
  annotations:
    #設置認證類型basic
    nginx.ingress.kubernetes.io/auth-type: basic
    #設置secret資源名稱basic-auth
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    #設置認證窗口提示信息
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - gxd'
spec:
  rules:
  - host: auth.gxd.com
    http:
      paths:
      - path: /
        backend:
          serviceName: svc-2  #之前指定創建過的svc
          servicePort: 80
==========================================================
kubectl apply -f ingress-auth.yaml 
kubectl get ingress

10.4 做端口映射並訪問測試

echo '192.168.10.30 auth.gxd.com' >> /etc/hosts

在瀏覽器訪問 http://auth.gxd.com:31396


十一、nginx進行重寫

11.1 配置說明

nginx.ingress.kubernetes.io/rewrite-target:<字符串>#必須重定向流量的目標URI
nginx.ingress . kubernetes.io/ssl-redirect:<布爾值>指示位置部分是否僅可訪問sSL(當Ingress包含證書時,默認為true)nginx.ingress . kubernetes.io/force-ssl-redirect:<布爾值>#即使Ingress未啟用rLS,也強制重定向到HTTPS
nginx.ingress .kubernetes.io/app-root:<字符串>#定義controller必須重定向的應用程序根,如果它在'/'上下文中·nginx.ingress, kubernetes.io/use-regex:<布爾值>#指示Ingress.上定義的路徑是否使用正則表達式

11.2 編寫yaml文件

vim ingress-rewrite.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-rewrite
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://auth.gxd.com:31396
spec:
  rules:
  - host: rewrite.gxd.com
    http:
      paths:
      - path: /
        backend:
          serviceName: ggggg  #由於rewrite.gxd.com只是用於跳轉不需要真實站點存在,因此svc資源名稱可隨意定義
          servicePort: 1111 
==========================================================
kubectl apply -f ingress-rewrite.yaml
kubectl get ingress

11.3 做端口映射並訪問測試

echo '192.168.10.30 rewrite.gxd.com' >> /etc/hosts

在瀏覽器訪問 http://rewrite.gxd.com



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM