Ingress控制器
Ingress控制器:
工作在7层的负载均衡器,支持http、https、负载均衡、域名。作用与service一样,但是实现效果有区别
功能基于软件实现
工作原理:

客户端请求时,到达ingress-nginx的pod,再调度到ingress控制器,ingress控制器再根据ingress的定义工作模式,访问service,由svc把请求转给pod
ingress-nginx的pod可以按需要选择运行方式
ingress控制器选择:
通过ingress类,可在集群中部署任意数量ingress控制器
- nginx
- traefik
- envoy
工作模式:
以nginx为例
- 虚拟主机方式
- location的url方式
运行方式:
- daemonset运行
- service代理运行
- 直接绑定物理机端口允许
安装ingress插件:
下载地址: https://codeload.github.com/kubernetes/ingress-nginx/
k8s版本支持记录: https://github.com/kubernetes/ingress-nginx
安装文档: https://kubernetes.github.io/ingress-nginx/deploy/
云平台使用loadbalance暴露控制器端口,裸机使用nodeport暴露端口
可能需要的配置,所有node节点都需要配置
由于直接使用的谷歌的镜像,需要配代理下载镜像,解决方法有:
1、去docker的hub上面去找替代的镜像
2、给containerd加代理
3、本地docker下载需要的镜像并导出,在node节点安装ctd的官方工具nerdctl(兼容docker指令),导入镜像文件
第一种
下载完镜像后,在配置文件中将用到镜像的地方改成这2个即可
docker pull bitnami/nginx-ingress-controller:1.8.1
docker pull jettech/kube-webhook-certgen:v1.5.2
第二种
参考docker实现:https://docs.docker.com/config/daemon/systemd/#httphttps-proxy
containerd:
#配置代理,需要win系统已经运行了代理且开启端口转发,我本地ssr已运行,所有代理地址是:winIP:转发端口
cat > /etc/sysconfig/containerd <<eof
HTTP_PROXY=http://192.168.0.101:1080
HTTPS_PROXY=http://192.168.0.101:1080
#这里是配置不通过代理访问的网络或域名,一定要加上当前集群网络也就是svc网段、pod网段,不然镜像能下载,但下载后回复master的数据就回不来了
NO_PROXY='127.0.0.1,2.2.2.0/24,1.1.1.0/24,192.168.0.0/16,10.20.0.0/16,10.10.0.0/16'
eof
sed -i '/Service/aEnvironmentFile=-/etc/sysconfig/containerd' `systemctl cat containerd |awk 'NR==1{print $2}'`
systemctl daemon-reload
systemctl restart containerd.service
systemctl show --property=EnvironmentFiles containerd
#删除配置
sed -i '/EnvironmentFile/d' /etc/systemd/system/containerd.service
systemctl daemon-reload
systemctl restart containerd.service
docker:
#docker的代理配置与上面containerd的类似,只用改名字即可,如果是docker 23.0支持 daemon.json中配置
vim /etc/docker/daemon.json
{
"proxies": {
"http-proxy": "http://192.168.0.101:1080",
"https-proxy": "http://192.168.0.101:1080",
"no-proxy": "127.0.0.1,2.2.2.0/24,1.1.1.0/24,192.168.0.0/16"
}
}
第三种
#在node节点下载工具,导入镜像,怎么下载镜像上传就不演示了
wget https://github.com/containerd/nerdctl/releases/download/v1.4.0/nerdctl-1.4.0-linux-amd64.tar.gz
tar xf nerdctl-1.4.0-linux-amd64.tar.gz -C /bin/
#加命令重命名,按个人意愿
echo "alias docker='nerdctl'" > /etc/profile.d/nerdctl-alias.sh
. /etc/profile
nerdctl load < 镜像1.tar
nerdctl load < 镜像2.tar
安装方法1:
wget -e 'HTTPS_PROXY=http://192.168.0.101:1080' https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/baremetal/deploy.yaml -O 0-ingress-ngx.yml
#修改配置,单独创建ingress控制器和svc端口暴露
sed -n '/apps\/v1/,/secretName: ingress-nginx-admission/p' 0-ingress-ngx.yml > 1-ingress-dep.yml
sed -i -e '/apps\/v1/,/secretName: ingress-nginx-admission/d' \
-e '/targetPort: http$/a\ nodePort: 30080' \
-e '/targetPort: https$/a\ nodePort: 30443' \
0-ingress-ngx.yml
kubectl apply -f 0-ingress-ngx.yml
#等待这个job创建出secret后再创建pod
kubectl logs -n ingress-nginx pods/ingress-nginx-admission-create-
#等一会后再创建
kubectl apply -f 1-ingress-dep.yml
kubectl get pods -n ingress-nginx


安装方法2:
wget -e 'HTTPS_PROXY=http://192.168.0.101:1080' https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/baremetal/deploy.yaml -O ingress-ngx.yml
sed -i -e '/targetPort: http$/a\ nodePort: 30080' \
-e '/targetPort: https$/a\ nodePort: 30443' \
ingress-ngx.yml
kubectl apply -f ingress-ngx.yml
#让ingress控制器的pod等待一段时间再启动
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=180s
测试使用:
kubectl create deployment demo --image=httpd --port=80
kubectl expose deployment demo
kubectl port-forward -n ingress-nginx service/ingress-nginx-controller 8080:80
#curl高级用法,直接指定解析ip地址,不用在hosts添加记录
#用法:--resolve 请求域名:请求端口:解析ip 域名
curl --resolve demo.localdev.me:8080:127.0.0.1 http://demo.localdev.me:8080
Kubectl delete deploy demo
kubectl delete svc demo

配置语法:
kubectl explain ing
apiVersion: networking.k8s.io/v1
kind: Igress
metadata:
annotations: #不同ingress支持不同的注解,当前ngx的注解官方文档:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
kubernetes.io/ingress.class: "nginx" #指定ingress控制器的类型,在注解指定的时候优先级高于spec.ingressClassName处指定。1.22版本之前有效,新版本不能用
nginx.ingress.kubernetes.io/rewrite-target: /$1 #重定向URI,v0.22.0后的版本不兼容以前的版本,用法和nginx的正则重写一样,用$1等位置变量
nginx.ingress.kubernetes.io/ssl-redirect: 布尔值 #是否只能通过SSL访问(当 Ingress 包含证书时默认为 True)
nginx.ingress.kubernetes.io/force-ssl-redirect: 布尔值 #未启用 TLS,也强制重定向到 HTTPS
nginx.ingress.kubernetes.io/app-root: str #控制器必须重定向的应用程序根(如果它位于 / 上下文中)
nginx.ingress.kubernetes.io/use-regex: 布尔值 #是否使用正则表达式
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" #代理连接超时
nginx.ingress.kubernetes.io/proxy-send-timeout: "600" #向后端发送请求数据的超时时间
nginx.ingress.kubernetes.io/proxy-read-timeout: "600" #读取后端数据时的超时时间
nginx.ingress.kubernetes.io/proxy-body-size: "50m" #客户端上传文件大小限制,默认还是原来的20m
nginx.ingress.kubernetes.io/app-root: /index.html #配置index文件
spec:
defaultBackend <Object> #未定义规则时,交给默认后端
resource <Object>
service <Object> #定义访问的后端service
name <str> #svc名称
port <Object> #端口
name
number
ingressClassName: "nignx" #代替旧的的注解kubernetes.io/ingress.class,但注解和此字段同时存在,注解覆盖此。当使用IngressClass来管理ingrees时,在配置
rules <Object> #定义规则,工作模式
- host: 域名 #主机名方式
#*.hj.com,可用通配符匹配,但:www.test.hj.com、hj.com这种不会匹配到,因为只匹配当前dns域,4级子域和2级域不在内
http #url路径方式
paths <Object>
- path <str> #location的url
pathType:匹配规则 #location匹配规则
#ImplementationSpecific ,混合下面两种
#Prefix,模糊匹配,区分大小写
#Exact,精准匹配,区分大小写
backend <Object> #定义ngx的upstream
service <Object>
name #代理pod的svc名称
port:
name
number: 端口
resource <Object> #资源和后端只能取一
apiGroup
kind
name
tls <Object>
hosts #tls的虚拟主机
secretName #证书名称
pathType字段3种类型的匹配

例1: ing+svc+nginx POD
1)先创建svc与后端nginx
apiVersion: v1
kind: Service
metadata:
name: ngx-svc
spec:
selector:
app: ngx
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ngx-dep
spec:
selector:
matchLabels:
app: ngx
template:
metadata:
labels:
app: ngx
spec:
containers:
- name: ngx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
2)再创建ingress访问入口
可以直接访问主机名,不用在nginx内部配置域名
可多个域名,第二个就不演示了
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ngx-ing
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/app-root: /index.html
spec:
ingressClassName: nginx
rules:
- host: www.hj.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ngx-svc
port:
number: 80
3)配置外部nginx(作为负载均衡器)
由于没有负载均衡器,只能用ngx模拟,将请求域名的的流量转给ingress
yum install -y nginx
cat > /etc/nginx/nginx.conf <<eof
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
}
stream {
upstream k8s {
server 2.2.2.15:30080;
server 2.2.2.25:30080;
server 2.2.2.35:30080;
server 2.2.2.45:30080;
}
server {
listen 80;
proxy_pass k8s; #仅tcp层面将访问80端口的请求都转给k8s入口控制器处理,由它控制器处理http协议
}
}
eof
systemctl start nginx
4)验证状态
检车rules是否匹配到域名
kubectl describe ing ingress-ngx
curl -L --resolve www.hj.com:80:127.0.0.1 www.hj.com


例2: ing绑定多域名、基于url转发
1)创建ing,可基于案例1清单文件做
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ngx-ing
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/app-root: /index.html
spec:
ingressClassName: nginx
rules:
- host: www.hj.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: ngx-svc
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: ngx-svc
port:
number: 80
- host: admin.hj.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ngx-svc-2
port:
number: 80
3)测试访问
curl --resolve www.hj.com:80:127.0.0.1 www.hj.com/app1
curl --resolve admin.hj.com:80:127.0.0.1 admin.hj.com

例3: 在ingress加上https
1)继续使用之前的tomat POD和svc
2)为tomcat创建证书,并基于kubectl自动导入
#查看绑定的nginx虚拟主机
kubectl describe ingress ingress-tomcat
#创建证书
mkdir ca ;cd ca
openssl genrsa -out tls.key 2048
openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=WH/L=WH/O=dev/CN=*.hj.com
#自动导入,配置证书
kubectl create secret tls www.hj.com-cert --cert=tls.crt --key=tls.key
kubectl get secrets
3)创建新的ingress配置
apiVersion: v1
kind: Service
metadata:
name: ngx-svc
spec:
selector:
app: ngx
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ngx-dep
spec:
selector:
matchLabels:
app: ngx
template:
metadata:
labels:
app: ngx
spec:
containers:
- name: ngx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ngx-ing
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/app-root: /index.html
spec:
ingressClassName: nginx
tls:
- hosts:
- www.hj.com
secretName: www.hj.com-cert
rules:
- host: www.hj.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ngx-svc
port:
number: 80
4)访问
curl -Lk --resolve https://www.hj.com:30443:127.0.0.1 https://www.hj.com:30443


浙公网安备 33010602011771号