什么是 Ingress
Ingress 为 Kubernetes 集群中的服务提供了入口,可以提供负载均衡,SSL 终止和基于名称的虚拟主机,在生产环境中常用的 Ingress 有 Treafik,Nginx,HAProxy,Istio 等。
通俗来讲,Ingress 和之前讲的 Service,Deployment 一样,也是一个 k8s 的资源类型,ingress 用于实现用域名的方式访问 k8s 内部的应用。
基本概念
在 Kubernetes 1.1 版本中添加的 Ingress 用于从集群外部到集群内部 Service 的 HTTP 和 HTTPS 路由,流量从 Internel 到 Ingress 再到 Service,最后到 Pod 上,通常情况下,Ingress 部署在所有的 Node 节点上。也可以部署在指定的几台节点上。
Ingress 可以配置提供服务外部访问的 URL,负载均衡,终止 SSL,并提供基于域名的虚拟主机。但 Ingress 不会暴露任意端口或协议。
Ingress 的安装
安装 helm 管理工具
下载 helm 版本包
1
wget https://get.helm.sh/helm-v3.5.3-linux-amd64.tar.gz
解压压缩包,并复制二进制文件到
/usr/local/bin
目录1
2tar zxvf helm-v3.5.3-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/检查 helm 安装是否成功
1
2
3
4
5
6
7
8
9
10
11# helm help
The Kubernetes package manager
Common actions for Helm:
- helm search: search for charts
- helm pull: download a chart to your local directory to view
- helm install: upload the chart to Kubernetes
- helm list: list releases of charts
....
安装 Ingress
添加 ingress 的 helm 仓库
1
2# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories查找 ingress 包版本
1
2
3# helm search repo ingress-nginx
NAME CHART VERSION APP VERSION DESCRIPTION
ingress-nginx/ingress-nginx 3.28.0 0.45.0 Ingress controller for Kubernetes using NGINX a...注意: ingress-nginx 为上一步中添加的 repo 名
下载 Ingress 的 helm 包到本地
1
helm pull ingress-nginx/ingress-nginx
下载好的 ingress 包会在当前目录
解压包,修改其中部分配置
1
2
3tar xf ingress-nginx-3.28.0.tgz
cd ingress-nginx
vim values.yaml需要修改的位置如下:
- Controller 和 admissionWebhook 的镜象地址,需要将公网镜像同步至公司内网镜像仓库;
- hostNetwork 的值设置为 true;
- dnsPolicy 设置为 ClusterFirstWithHostNet;
- NodeSelector 添加 ingress: “true” ,方便部署到指定节点;
- 资源类型更改为 kind: DaemonSet;
- 修改端口类型 type: LoadBalancer 为 type: ClusterIP
部署 ingress,给需要部署 ingress 的节点打上标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34# kubectl label nodes k8s-node-01 ingress=true
node/k8s-node-01 labeled
# kubectl label nodes k8s-node-02 ingress=true
node/k8s-node-02 labeled
# kubectl create ns ingress-nginx
namespace/ingress-nginx created
# helm install ingress-nginx -n ingress-nginx .
输出如下:
NAME: ingress-nginx
LAST DEPLOYED: Thu Apr 8 21:04:36 2021
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
...
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls将 ingress Controller 部署至 Node 节点。(ingress controller 不能部署在master节点,生产环境最少三个ingress controller,并且最好是独立的节点)
1
2kubectl label node k8s-node-01 ingress=true
kubectl label node k8s-master-03 ingress-查看安装状态
1
2
3
4
5
6
7
8# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller ClusterIP 10.96.226.185 <none> 80/TCP,443/TCP 3m7s
ingress-nginx-controller-admission ClusterIP 10.106.197.4 <none> 443/TCP 3m7s
# kubectl get ds -n ingress-nginx
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
ingress-nginx-controller 2 2 0 2 0 ingress=true 3m38s
Ingress 入门使用
创建一个单域名的 ingress
创建一个简单的 ingress.yaml 文件,内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
name: example
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: nginx-svc
servicePort: 80
path: /注释:
- apiVersion: ingress 的 api 接口版本,推荐使用 networking.k8s.io/v1beta1 或者 networking.k8s.io/v1;注意版本 v1beta1 在 1.22 版本后将被弃用;
- metedata.annotations.kubernetes.io/ingress.class: 一个集群中可能存在多个 ingress,该字段用来控制与哪个 ingress 进行关联;安装 ingress 时可以在 values.yaml 文件中进行定义;如下
- metadata.name: 创建 igress 资源的名称;
- spec.rules: 固定写法,一个 ingress 中可以配置多个域名;
- spec.rules.host: 域名,支持正则,如 *.bar.com;
- spec.rules.paths.backend: 后端关联 svc 的相关属性,比如 svc 名称,svc 端口
- spec.rules.paths.path: 访问的路径。和 nginx 配置中的 location 属性一样,可以使网站根目录,也可以是二级目录等;
使用 kubectl 创建 ingress
1
2
3
4
5
6
7
8# kubectl create -f ingress.yaml
Warning: networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.networking.k8s.io/example created
# kubectl get ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example <none> foo.bar.com 10.96.226.185 80 20s测试访问 foo.bar.com。正式环境应该是将域名解析到 LB 服务器或者代理服务器,然后由代理服务器在转发请求到安装了 ingress 服务的 Node 节点上;这里使用修改 hosts 解析的方式;配置如下
1
2
3
4
5
6
7# 查看安装了 ingress 的节点的 IP 地址
# kubectl get pods -n ingress-nginx -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-7dnnn 1/1 Running 1 22h 192.168.200.21 k8s-node-01 <none> <none>
# 修改 hosts
echo '192.168.200.21 foo.bar.com' >> /etc/hosts打开浏览器,测试访问,效果如下
使用 ingress-nginx 暴露 kubernetes-dashboard 服务
创建 ingress.yaml 文件,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubernetes-dashboard
namespace: kubernetes-dashboard
annotations:
# 开启use-regex,启用path的正则匹配
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /
# 默认为 true,启用 TLS 时,http请求会 308 重定向到https
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
ingressClassName: nginx
rules:
- host: dashboard.vonebaas.com
http:
paths:
- backend:
service:
name: kubernetes-dashboard
port:
number: 443
path: /
pathType: ImplementationSpecific创建资源对象
1
kubectl create -f ingress.yaml