什么是ingress
通俗来讲,ingress 和Service、Deployment 都是 kubernetes 的资源类型,Ingress 用于实现用域名的方式访问K8s 内部应用。
Ingress 安装
首先安装 helm 管理工具:https://helm.sh/docs/intro/install/
使用 helm 安装Ingress:https://kubernetes.github.io/ingress-nginx/deploy/
1.添加 Ingress 的 helm 仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
2.下载 ingress 的 helm 包至本地
helm pull ingress-nginx/ingress-nginx
3.更改对应的配置
tar xf ingress-nginx-3.6.0.tgz
cd ingress-nginx
vim values.yaml
4.需要修改的位置
- Controller 和 admissionWebhook 的镜像地址,需要将公网镜像同步至公司内网镜像仓库。
- hostNetwork 设置为true
- dnsPolicy 设置为 ClusterFirstWithHostNet
- NodeSelector 添加 ingress:“true” 部署至指定节点
- 类型更改为kind:DaemonSet
5.部署 ingress
给需要部署ingress 的节点上打标签
$ kubectl label node k8s-master03 ingress=true
$ kubectl create ns ingress-nginx
$ helm install ingress-nginx -n ingress-nginx
Ingress 使用
一个Ingress 资源示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
Ingress 需要指定 apiVersion
、kind
、 metadata
和 spec
字段。 Ingress 对象的命名必须是合法的 DNS 子域名名称。
service 和 deployment YAML 如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- port: 80
使用 kubectl apply -f
创建
$ kubectl apply -f nginx-ingress.yaml -f nginx-svc.yaml
http://foo.bar.com
转发到集群内的服务 nginx-svc
上,完整的URL为http://nginx-svc:80/
。
配置 /etc/hosts
文件,如下所示:
192.168.31.217 foo.bar.com
在浏览器上访问foo.bar.com
,就可以看到内容了
默认后端
没有设置规则的 Ingress 将所有流量发送到同一个默认后端,.spec.defaultBackend 则是在这种情况下处理请求的那个默认后端。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-backend
spec:
defaultBackend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: static-assets
rules:
- http:
paths:
- path: /icons
pathType: ImplementationSpecific
backend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: icon-assets
路径类型
Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。当前支持的路径类型有三种:
ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。
Exact:精确匹配 URL 路径,且区分大小写。
Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。
类型 | 路径 | 请求路径 | 匹配与否? |
---|---|---|---|
Prefix | / |
(所有路径) | 是 |
Exact | /foo |
/foo |
是 |
Exact | /foo |
/bar |
否 |
Exact | /foo |
/foo/ |
否 |
Exact | /foo/ |
/foo |
否 |
Prefix | /foo |
/foo , /foo/
|
是 |
Prefix | /foo/ |
/foo , /foo/
|
是 |
Prefix | /aaa/bb |
/aaa/bbb |
否 |
Prefix | /aaa/bbb |
/aaa/bbb |
是 |
Prefix | /aaa/bbb/ |
/aaa/bbb |
是,忽略尾部斜线 |
Prefix | /aaa/bbb |
/aaa/bbb/ |
是,匹配尾部斜线 |
Prefix | /aaa/bbb |
/aaa/bbb/ccc |
是,匹配子路径 |
Prefix | /aaa/bbb |
/aaa/bbbxyz |
否,字符串前缀不匹配 |
Prefix |
/ , /aaa
|
/aaa/ccc |
是,匹配 /aaa 前缀 |
Prefix |
/ , /aaa , /aaa/bbb
|
/aaa/bbb |
是,匹配 /aaa/bbb 前缀 |
Prefix |
/ , /aaa , /aaa/bbb
|
/ccc |
是,匹配 / 前缀 |
Prefix | /aaa |
/ccc |
否,使用默认后端 |
混合 |
/foo (Prefix), /foo (Exact) |
/foo |
是,优选 Exact 类型 |
主机名通配符
主机名可以是精确匹配(例如 foo.bar.com
),也可以使用通配符匹配(例如 *.bar.com
)。精确匹配要求 HTTP host 头部字段与 host 字段一致,通配符匹配要求 HTTP host 头部字段与通配符规则中的后缀部分相同。
主机 | host 头部 | 匹配与否? |
---|---|---|
*.foo.com |
bar.foo.com |
基于相同的后缀匹配 |
*.foo.com |
baz.bar.foo.com |
不匹配,通配符仅覆盖了一个 DNS 标签 |
*.foo.com |
foo.com |
不匹配,通配符仅覆盖了一个 DNS 标签 |
将同一域名的不同 URL 路径转发到不同的服务(Simple Fanout)
根据请求的 HTTP URI 将来自同一 IP 地址的流量路由到多个 Service。
Ingress 配置如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
使用 kubectl apply -f
创建 Ingress
$ kubectl apply -f ingress.yaml
查看 Ingress 详细信息
$ kubectl describe ingress simple-fanout-example
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
将不同的域名转发到不同的服务
基于名称的虚拟主机支持将针对多个主机名的 HTTP 流量路由到同一 IP 地址上。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: bar.foo.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service2
port:
number: 80
HTTPS 配置
通过设定包含 TLS 私钥和证书的 Secret 来保护 Ingress。 Ingress 只支持单个 TLS 端口 443。 TLS Secret 的数据中必须包含用于 TLS 的以键名 tls.crt
保存的证书和以键名 tls.key
保存的私钥。
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 编码的证书
tls.key: base64 编码的私钥
type: kubernetes.io/tls
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
更新 Ingress
可以使用 kubectl edit
更新 Ingress ,也可以使用 kubectl replace -f
更新 ingress.yaml 文件。