通常情况下,service和pod的IP仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到service在Node上暴露的NodePort上,然后再由kube-proxy将其转发给相关的Pod。本文示例为k8s 1.18版本。
一、Ingress 概述
Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。
Ingress 可以提供负载均衡、SSL 和基于名称的虚拟托管。
二、Ingress 是什么
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。
Ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置, 然后对外部提供服务。ingress包括:ingress controller和ingress resources。
ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy,
trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。
三、Ingress 部署
必须具有 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。
3、1 部署 Ingress controller
安装 Ingress-Nginx
首先需要在官网下载对应的安装 yaml
文件,可以使用该 下载文件 进行安装。
安装的过程中,根据部署文件其会自行定义一个名为 ingress-nginx
的名称空间,由来保存其对应的 Pod
和内容。而 Deployments
中会自动部署一个名为 nginx-ingress-controller
的服务,用于管理和控制 Ingress
服务。还有对应 Deployment
的 ingress-nginx
的 SVC
也会一同创建的。同时还有相关的角色、ConfigMap
等等。
# 本文k8s版本是1.18 所以可以用v0.40.0,如果是其他版本参考ingress-nginx官网说明
# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.40.0/deploy/static/provider/cloud/deploy.yaml
# 因为是在内网k8s使用,所以service用nodePort
# vim deploy.yaml
......
ingress-nginx Service type 类型由 LoadBalancer 改成 NodePort
......
# 配置中 k8s.gcr.io/ingress-nginx/controller:v0.40.0 镜像是从海外机器下载导出并导入到节点机的
# kubectl apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
查看ingress-controller的service
# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 172.16.0.22 <none> 80:30294/TCP,443:32133/TCP 149m
访问 master或者 ingress controller 落点节点(pod 部署为DaemonSet的话,每个节点都可访问)
# curl 10.10.1.24:30294 # 1.24 为ingress-controller pod落点节点IP
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
.....
# 此时应该是404 ,调度器是正常工作的,只是后端服务没有关联
3、2 部署 Ingress 资源
- 部署一个 deployment pod
# cat deploy-nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# kubectl create -f deploy-nginx.yml
- 部署 deployment service
# cat nginx-svc-test.yml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
namespace: default
spec:
ports:
- nodePort: 30080
port: 30080
targetPort: 80
selector:
app: nginx
type: NodePort
# kubectl create -f nginx-svc-test.yml
- 部署 Ingress 资源
# cat ingress-demo.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
spec:
rules:
- host: www.365you.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 30080
# kubectl create -f ingress-demo.yml
- Ingress 访问测试(访问的是ingress-nginx-controller svc)
# 配置本地hosts
# echo "10.10.1.24 www.365you.com" >> /etc/hosts
# 端口30294 对应上面的ingress-nginx-controller svc 端口
# 输出内容是我修改了service pod 界面
# curl www.365you.com:30294
test-222
四、Ingress 类型规则
4、1 静态资源后端
# cat ingress-resource-backend.yaml
apiVersion: extensions/v1beta1
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
4、2 基于主机名称的虚拟主机
# cat ingress-wildcard-host.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80
4、3 基于URL路径匹配
# cat simple-fanout-example.yaml
apiVersion: extensions/v1beta1
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
五、Ingress TLS 配置
- 根据证书生成secret
# kubectl create secret tls ingress-secret-365you --cert=365you_com.crt --key=365you.com.key
- 更新 Ingress 配置
# cat ingress-nginx.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
spec:
tls: # 添加上证书配置
- hosts:
- www.365you.com
secretName: ingress-secret-365you
rules:
- host: www.365you.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 30080
# kubectl replace -f ingress-nginx.yml
ingress.extensions/nginx-test configured
-
Ingress TLS 测试
六、Ingress 规则重写
- 规则列表
名称 | 描述 | 值 |
nginx.ingress.kubernetes.io/rewrite-target | 必须重定向的目标URL | String |
nginx.ingress.kubernetes.io/ssl-redirect | 指示位置部分是否只能由SSL访问(当Ingress包含证书时,默认为True) | Bool |
nginx.ingress.kubernetes.io/force-ssl-redirect | 即使Ingress没有启用TLS,也强制重定向到HTTPS | Bool |
nginx.ingress.kubernetes.io/app-root | 定义应用程序根目录,Controller在“/”上下文中必须重定向该根目录 | String |
nginx.ingress.kubernetes.io/use-regex | 指示Ingress上定义的路径是否使用正则表达式 | Bool |
- 演示示例
# cat ingress-demo.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: https://www.qq.com
spec:
tls:
- hosts:
- www.365you.com
secretName: ingress-secret-365you
rules:
- host: www.365you.com
http:
paths:
- path: /
backend:
serviceName: nginx
servicePort: 30080
# kubectl replace -f ingress-demo.yml
Reference:
https://kubernetes.github.io/ingress-nginx/deploy/
https://www.kubernetes.org.cn/ingress
https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
https://blog.csdn.net/woshizhangliang999/article/details/108762012
https://kubernetes.github.io/ingress-nginx/examples/auth/basic/