今天将会讲解 Ingress 这个元件
包括用途, 用法还有实际案例
假设我们布署了一个 my-app 的 Pod
当想要透过浏览器去存去这个 my-app
有一个作法是建立一个 my-app 的外部 Service
这样一来就可以透过 Service 的外部 IP 加上对外开放服务的 Port 来存取 my-app
但这种作法其实很不方便 因为必须去找到 Service 的外部 IP
这时候就会需要 Ingress 这个元件来提供域名服务
让使用者透过域名来存取 my-app 如下图:
apiVersion: v1
kind: Service
metadata:
name: myapp-external-service
spec:
selector:
app: myapp
type: LoadBalancer
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 35010
External Service 的类型是 LoadBalancer
代表会给予一个对外的 IP
指定的 nodePort 是给外部存取 Service 的接口
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: myapp.com
http:
paths:
- backend:
serviceName: myapp-internal-service
servicePort: 8080
Ingress 的类型是 Ingress
spec 的 rules 是设定路由规则
以这边的例子规则是所有域名是 myapp.com 的封包都 forward 到 myapp-internal-service:8080
paths 这边就是设定 url
注意的是, 这里的 http 指的是 myapp-internal-service 所服务的 protocol 而不是外部的 protocol
而对应的 Internal Service 如下:
apiVersion: v1
kind: Service
metadata:
name: myapp-internal-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 8080
targetPort: 8080
host 需要是一个合法的域名
host 用来把外部域名, 对应到 Node IP Address
除了刚刚设定之外
Ingress 发布需要一个 Ingress 实作实体, 也就是所谓 Ingress Controller
Ingress Controller 是实际在执行路由的实体, 会根据 Ingress 的 rules 来直接封包路由
架构图如下:
Ingress Controller 的实作有很多第三方套件可以用
k8s 官方提供可用的 Ingress Controller 选项
而实际布署要选用哪种 Ingress Controller 要根据 k8s 丛集建制环境来决定
假设是建立在云服务商上面的话
可能就有云服务商提供的选项, 所谓 cloud load balancer
而使用云服务商提供的 cloud load balancer, 举例来说: AWS 的 ELB
好处就是不必自行去实现负载平衡的功能
架构如下:
但如果是没有用云服务商, 而是像是使用 minikube 这类 local run 的丛集的话
就要自行架设 load balancer, 可以是在丛集之内或是之外的服务器
安全一点的作法一台服务器当 proxy 转发封包到 Ingress Controller
这样对外的接口就只有那台 proxy server, 而 k8s cluster 就不需有对外的接口
架构图如下:
minikube addons enable ingress
这个设定是自动启用了 k8s Nginx 的 Ingress Controller
这个设定也可以用在 production 环境
当 ingress 被 enabled 之後可以查询 namespace 是 ingress-nginx 的 Pod
执行以下指令
minikube dashboard
之後就可以透过 localhsot 察看 minikube 的 status
会发现多了一个 namespace 叫作 kubernete-dashboard
查询这个 namespace 下面的 Pod
会发现 kubernetes-dashboard 这个 Service 没有对外开放
所以需要使用 Ingress 建立路由才存取
目标建立 hostname 为 dashboard.com 来存取 kuberenetes-dashboard 这个 Service 内容
建立 dashboard-ingress.yaml 如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
spec:
rules:
- host: dashboard.com
http:
paths:
- pathType: ImplementationSpecific
backend:
service:
name: kubernetes-dashboard
port:
number: 80
语法参考自k8s 官方文件
关键点:
1 设定 host 为 dashboard.com(你想要设定域名)
2 设定 service 的 name 还有 port 到要连结的 Service
举例来说: 这边的 name 设定是 kubernetes-dashboard, port 是 80
因为前面 kubectl get pod -n kuberenetes-dashboard 结果
3 设定 metadata 内, 对应的 namespace 为 kuberenetes-dashboard
因为这是属於 kuberenetes-dashboard 类别所有放在这个 namespace
另外因为这样放 可以让 service 的 name url 的比较简单, 如果放在不同 namespace 则必须要指定 kuberenetes-dashboard Service 的 namespace
4 kind 是 Ingress 类别
5 pathType 是 ImplementationSpecific, 这里类别有三种 Exact, Prefix, ImplementationSpecific. Exact 代表 path 要完全一样才进入路由, Prefix 代表只要前置有包换就进入路由, ImplementationSpecific 代表根据 IngressClass 来决定
6 Ingress Class 是由 Ingress Controller 所提供的选项
每个 Ingress Controller 会实作自己的比对模式并对应到一种 Ingress Class
所以这边的 Ingress Class 要去查询 Ingress Controller 所提供的类别
使用以下指令, 发布 Ingress
kubectl apply -f dashboard-ingress.yaml
检查 ingress
这时候如果直接 到浏览器
从 http://dashboard.com 输入
就会发现
原因是因为我们只设定好路由
但是没做域名转换
因此在本机电脑这边需要 在 /etc/hosts 内 加入下面一行
192.168.49.2 dashboard.com
注意的是 这边前面的 192.168.49.2 是从
kubectl get ingress -n kubernetes-dashboard
拿到的 IP 随着每个人电脑不同会有不同的结果
修改完 /etc/hosts 存档之後
重新再浏览器输入 http://dashboard.com
透过以下指令
kubectl describe ingress dashboard-ingress -n kubernetes-dashboard
会发现有一个 Default backend 的栏位
而这个是 Ingress 用来处理没被原本 Service 定义路由的 request
但这边可以看到还没有给予任何 Service 来处理
所以再处理 request 时 假设遇到没有被 forward 过去的 Service 处理到的路由
就会跳出一些 404 网页找不到 等等预设错误
而不是客制化的错误页面
想要建立一个客制化页面
来处理此问题的方式就是建立一个 Internal Service 对应到这个 default-http-backend
在这个 Internal Service去实作客制化的页面
建立 default-http-backend.yaml 如下
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
spec:
selector:
app: default-response-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
由於处理方式很多, 在此就不做更深入实作
除了刚刚那个直接对应的 Service 的路由
Ingress 也支援多个路由对应的方式
举例如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: myapp.com
http:
paths:
- path: "/analytics"
path: Prefix
backend:
service:
name: analytics-service
port:
number: 3000
- path: "/shopping"
pathType: Exact
backend:
service:
name: shopping-service
port:
number: 8080
就可以做到以下的路由
Ingress 也支援多个子域名对应的方式
举例如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress-no-third-host
spec:
rules:
- host: analytics.myapp.com
http:
paths:
- path: "/"
path: Prefix
backend:
service:
name: analytics-service
port:
number: 3000
- host: shopping.myapp.com
http:
- path: "/"
pathType: Exact
backend:
service:
name: shopping-service
port:
number: 8080
就可以做到以下的路由
要建立 TLS 必须要先建立 certificate 跟 key pair
然後把 certificate 跟 private 放在 Secret 内
建立 sample-tls-secret.yaml 如下:
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
然後在 Ingress 设定内取用这个 Secret 在 tls 设定的部份
建立 tls-example-ingress.yaml 如下
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- https-example.foo.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
关键点:
1 tls 设定的 hosts 一定要跟 rules 内指令的 host 一样
2 这个范例是根据nginx的规则所写, 不同的 Ingress Controller 可能会有不同的 tls 设定
3 secretName 对应到刚刚 TLS 建立的 Secret 名称
4 Secret 与 Ingress 必须建立在同一个 Namespace
<<: Day09: 【TypeScript 学起来】物件型别 Object Types : Arrays / Function
今天要来介绍 CSS 命名 首先先来介绍 驼峰式命名: https://zh.wikipedia.o...
我们可以在一般的静态URL网址上加上动态路由参数,在 URL 中设置动态参数允许路由在将 URL ...
前言 身为一位 常常在使用容器的开发者 对於容器的管理是一件很重要的事情 特别是在大量使用容器的时候...
下面三种座标的(x,y)都是从左上角开始为(0,0) screen 根据整个萤幕的宽高 page 根...
闲话家常 用Laravel开发系统,那就用Laradock架设环境吧! 首先到 Laradock 下...