k8s之nginx-ingress

一、Ingress 簡介

在Kubernetes中,服務和Pod的IP地址僅可以在集群網絡內部使用,對于集群外的應用是不可見的。為了使外部的應用能夠訪問集群內的服務,在Kubernetes 目前 提供了以下幾種方案:

  • NodePort
  • LoadBalancer
  • Ingress

Ingress 可以解決什么問題

1.動態配置服務
  如果按照傳統方式, 當新增加一個服務時, 我們可能需要在流量入口加一個反向代理指向我們新的k8s服務. 而如果用了Ingress, 只需要配置好這個服務, 當服務啟動時, 會自動注冊到Ingress的中, 不需要而外的操作.
2.減少不必要的端口暴露
  配置過k8s的都清楚, 第一步是要關閉防火墻的, 主要原因是k8s的很多服務會以NodePort方式映射出去, 這樣就相當于給宿主機打了很多孔, 既不安全也不優雅. 而Ingress可以避免這個問題, 除了Ingress自身服務可能需要映射出去, 其他服務都不要用NodePort方式

二、Ingress工作原理

ngress 簡單的理解就是你原來需要改 Nginx 配置,然后配置各種域名對應哪個 Service,現在把這個動作抽象出來,變成一個 Ingress 對象,你可以用 yaml 創建,每次不要去改 Nginx 了,直接改 yaml 然后創建/更新就行了;那么問題來了:”Nginx 該怎么處理?”

Ingress Controller 這東西就是解決 “Nginx 的處理方式” 的;Ingress Controoler 通過與 Kubernetes API 交互,動態的去感知集群中 Ingress 規則變化,然后讀取他,按照他自己模板生成一段 Nginx 配置,再寫到 Nginx Pod 里,最后 reload 一下,工作流程如下圖:

nginx-ingress.png

實際上Ingress也是Kubernetes API的標準資源類型之一,它其實就是一組基于DNS名稱(host)或URL路徑把請求轉發到指定的Service資源的規則。用于將集群外部的請求流量轉發到集群內部完成的服務發布。我們需要明白的是,Ingress資源自身不能進行“流量穿透”,僅僅是一組規則的集合,這些集合規則還需要其他功能的輔助,比如監聽某套接字,然后根據這些規則的匹配進行路由轉發,這些能夠為Ingress資源監聽套接字并將流量轉發的組件就是Ingress Controller。

三、部署Ingress

部署環境:centos-7.6
kubernetes-1.16.0
Docker version 19.03.4
nginx-ingress-controller-0.16.2
defaultbackend-1.4

1.準備Ingres鏡像
把Igress所需鏡像在nginx-ingress/docker_image目錄的鏡像到導入k8s的node節點或者導進harbor (鏡像已打包好)
部署相關yaml文件和鏡像請訪問:鏈接: https://pan.baidu.com/s/1jBEJKQG4CuIo299JytKl0A 提取碼: vhue

也可以通過官網下載最新yaml(網速比較慢)

wget  https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml 

下載后進入相關目錄

[root@master-01 nginx-ingress]# tree 
.
├── docker_image(鏡像)
│   ├── defaultbackend.tar.gz
│   └── nginx-ingress-controller_0.16.2.tar.gz
└── yaml(ingress配置文件)
    └── nginx-ingress.tar.gz

手動導入到要運行Ingress的node節點
導入方法

[root@jenkins ~]# cat nginx-ingress-controller:0.16.2.tar.gz | docker import - #導入nginx-ingress的控制器鏡像
sha256:531e7aea5ce40a57e18d57bd2d1149e16972dfe9ab633bca8b58ae2df486fff7

[root@jenkins ~]# cat defaultbackend.tar.gz | docker import - #導入defaultbackend鏡像
sha256:03ca9819157b3ff9daf7cb1a96b984a4eb7881d16ac3e2ff5d46c8b38729882c

檢查鏡像是否導進去

root@jenkins ~]# docker image ls
REPOSITORY                                                        TAG                 IMAGE ID            CREATED              SIZE
busybox                                                           latest              020584afccce        4 weeks ago          1.22MB
registry.aliyuncs.com/google_containers/kube-apiserver            v1.16.0             b305571ca60a        2 months ago         217MB
registry.aliyuncs.com/google_containers/kube-controller-manager   v1.16.0             06a629a7e51c        2 months ago         163MB
registry.aliyuncs.com/google_containers/kube-proxy                v1.16.0             c21b0c7400f9        2 months ago         86.1MB
registry.aliyuncs.com/google_containers/kube-scheduler            v1.16.0             301ddc62b80b        2 months ago         87.3MB
registry.aliyuncs.com/google_containers/etcd                      3.3.15-0            b2756210eeab        2 months ago         247MB
registry.aliyuncs.com/google_containers/coredns                   1.6.2               bf261d157914        3 months ago         44.1MB
quay.io/coreos/flannel                                            v0.11.0-amd64       ff281650a721        10 months ago        52.6MB
harbor-ali.ejoyst.com/k8s_img/nginx-ingress-controller            0.16.2              c5ac2be3012c        17 months ago        362MB
harbor-ali.ejoyst.com/k8s_img/defaultbackend                      1.4                 846921f0fe0e        2 years ago          4.84MB

2.準備yaml文件

解壓nginx-ingress.tar.gz

[root@master-01 nginx-ingress]# cd yaml/
[root@master-01 yaml]# ls
nginx-ingress.tar.gz
[root@master-01 yaml]# tar xfz nginx-ingress.tar.gz 
[root@master-01 yaml]# ls
ingress  nginx-ingress.tar.gz
[root@master-01 yaml]# ls ingress/
01-configmap.yaml           03-default-backend.yaml       05-nginx-ingress-service.yaml.bak  myapp-pod-ingress.yaml
02-nginx-ingress-rbac.yaml  04-nginx-ingress-deploy.yaml  myapp-ingress.yaml

因為我是從自己搭建的harbor去拉取鏡像的,如果是拉取本地鏡像,需要根據需求修改一下幾個地方
1.修改03-default-backend.yaml
注釋一些行

 ...
 
 20  #     imagePullSecrets:
 21  #     - name: regsecret
 27         image: harbor-ali.abc.com/k8s_img/defaultbackend:1.4 改為k8s.gcr.io/k8s_img/defaultbackend:1

 44 #      nodeSelector: 
 45 #        node-label: "prod"
 ...

2.修改04-nginx-ingress-deploy.yaml 注釋一下行

 ...
 25 #      imagePullSecrets:
 26 #      - name: regsecret
 29           image: harbor-ali.abc.com/k8s_img/nginx-ingress-controller:0.16.2 改為 image: k8s.gcr.io/nginx-ingress-controller:0.16.2 
 79 #      nodeSelector:
 80 #        node-label: "prod"
 ....

3.依次創建ingress的yaml

[root@master-01 ingress]# kubectl apply -f 01-configmap.yaml 
configmap/nginx-ingress-configuration created
configmap/nginx-ingress-tcp-services created
configmap/nginx-ingress-udp-services created

[root@master-01 ingress]# kubectl apply -f 02-nginx-ingress-rbac.yaml 
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

[root@master-01 ingress]# kubectl apply -f 03-default-backend.yaml 
deployment.apps/default-http-backend created
service/default-http-backend created

[root@master-01 ingress]# kubectl apply -f 04-nginx-ingress-deploy.yaml 
deployment.apps/nginx-ingress-controller created
service/nginx-ingress-service created

4.檢查相關服務是否正常

[root@master-01 ingress]# kubectl get deploy -n kube-system
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
coredns                    2/2     2            2           14d
default-http-backend       1/1     1            1           2m27s
nginx-ingress-controller   1/1     1            1           2m21s

[root@master-01 ingress]# kubectl get svc -n kube-system
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default-http-backend    ClusterIP   10.104.194.108   <none>        80/TCP                   3m25s
kube-dns                ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   14d
nginx-ingress-service   NodePort    10.97.84.182     <none>        80:30080/TCP             3m20s  (30080為對外服務的端口)

瀏覽器訪問ingress服務端口看是否正常,出現了一下404畫面說明工作組件是正常的

image.png

部署已經完成了

四.Ingress應用實例

1.創建一個后端的應用實例myapp


[root@master-01 ingress]# ls
01-configmap.yaml           03-default-backend.yaml       05-nginx-ingress-service.yaml.bak  myapp-pod-ingress.yaml
02-nginx-ingress-rbac.yaml  04-nginx-ingress-deploy.yaml  myapp-ingress.yaml
[root@master-01 ingress]# 


[root@master-01 ingress]# cat myapp-pod-ingress.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp-ingress
spec:
  selector:
    app: myapp
    release: canary
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      imagePullSecrets:     #本地拉鏡像要注釋
      - name: regsecret       #本地拉鏡像要注釋
      hostAliases:
        - ip: "10.1.1.5"
          hostnames:
          - "harbor-ali.abc.com"
      containers:
      - name: myapp
        image: "harbor-ali.abc.com/k8s_img/myapp:v1"     # 本地拉取鏡像可改為(ikubernertes/myapp:v1)
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 80
      nodeSelector:         # 本地拉取鏡像可注釋
        node-label: "test"   # 本地拉取鏡像可注釋
        
        

檢查服務是否正常

[root@master-01 ingress]# kubectl apply -f myapp-pod-ingress.yaml
service/myapp-ingress created
deployment.apps/myapp-ingress created
[root@master-01 ingress]# kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP   14d
myapp           ClusterIP   None            <none>        80/TCP    27h
myapp-ingress   ClusterIP   10.97.204.179   <none>        80/TCP    13s



[root@master-01 ingress]# kubectl get pod
NAME                                   READY   STATUS             RESTARTS   AGE

myapp-ingress-6c94846d6f-9vmfm         1/1     Running            0          34s

2.將myapp-ingress服務添加到ingress中

[root@master-01 ingress]# cat myapp-ingress.yaml 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-myapp
spec:
  rules:
  - host: myapp.ingress.com         #自定義域名,訪問時記得配hosts解析
    http:
      paths:
      - path:
        backend:
          serviceName: myapp-ingress    #關聯應用的service服務
          servicePort: 80               #服務暴露的端口

創建ingress

[root@master-01 ingress]# kubectl apply -f myapp-ingress.yaml 
ingress.extensions/ingress-myapp created
[root@master-01 ingress]# kubectl get ingress 
NAME            HOSTS               ADDRESS   PORTS   AGE
ingress-myapp   myapp.ingress.com             80      6s

  • 驗證:
    在其他主機訪問模擬外網訪問ingress暴露的端口看是否可以訪問到myapp服務,也可以在瀏覽器訪問
[root@jenkins ~]# curl http://myapp.ingress.com:30080
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

說明可以通過nginx-ingress暴露的30080端口代理訪問到我們后端的pod應用

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容