一、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 一下,工作流程如下圖:
實際上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畫面說明工作組件是正常的
部署已經完成了
四.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應用