ingress
官方网站
ingress
仓库地址
原来我们需要将端口号对外暴露,通过ip+端口号就可以访问
原来是使用service中的NodePort实现的
但是NodePort还存在一些缺陷
Pod和Ingress都是通过service进行关联的,而作为统一入口,由service关联一组pod中
实际访问中,我们都是有域名的,维护很多域名,a.com和b.com
然后不同的域名对应不同的service,然后service 管理不同的pod
需要注意ingress不是内置的组件,需要我们单独安装。
下面我们通过yaml的方式,部署我们的ingress,配置如下
# 下载对应的yml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml
# 替换镜像地址(国内无法下载)
sed -i '[email protected]/ingress-nginx/controller:v1.1.1\(.*\)@duangx/ingress-nginx-controller:v1.1.@' deploy.yaml
sed -i '[email protected]/ingress-nginx/kube-webhook-certgen:v1.1.1\(.*\)$@duangx/kube-webhook-certgen:v1.1.1@' deploy.yaml
# 修改yml文件名
mv deploy.yaml ingress-nginx.yaml
# 部署
kubectl apply -f ingress-nginx.yaml
# 卸载
kubectl delete -f ingress-nginx.yaml
# 创建命名空间
kubectl create ns test
# 在test命名空间创建nginx
kubectl create deployment test-ingress --image=nginx -n test
# 暴漏端口
kubectl expose deployment test-ingress --port=80 --target-port=80 --type=NodePort -n test
创建ingress服务
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
namespace: test
spec:
rules:
- host: www.ixx.com # 自定义的域名
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: test-ingress # 上面创建的服务名 svc
port:
number: 80
访问 www.ixx.com 发现访问不通
查看nginx ingress contrller svc 发现 ingress-nginx-controller 的 EXTERNAL-IP 一直pending
[root@k8smaster ingress]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.96.161.205 80:30657/TCP,443:30521/TCP 138m
ingress-nginx-controller-admission ClusterIP 10.96.178.244 443/TCP 138m
# 查看 ingress-nginx-ctroller 节点
[root@k8smaster ingress]# kubectl get po -n ingress-nginx -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create--1-rp5dt 0/1 Completed 0 153m 10.244.243.1 mcn-test
ingress-nginx-admission-patch--1-w2vrg 0/1 Completed 3 (153m ago) 153m 10.244.206.65 mcn-prod
ingress-nginx-controller-69d84f9c5f-vv9sb 1/1 Running 0 147m 10.244.206.67 mcn-prod
# 修改 EXTERNAL-IP为 ingress-nginx-controller(mcn-prod) 的ip(内网))
kubectl edit -n ingress-nginx service/ingress-nginx-controller
# 添加 externalIPs:
访问 http://www.ixx.com/ (这个其实不是我们启动的nginx)
进入容器修改默认页面
# 进入容器
kubectl exec -it test-ingress-5c4bb6ff8-kl9ql /bin/bash -n test
[root@k8smaster ~]# kubectl exec -it test-ingress-5c4bb6ff8-kl9ql /bin/bash -n test
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@test-ingress-5c4bb6ff8-kl9ql:/# echo "test-nginx" > /usr/share/nginx/html/index.html
再次访问
查看 ingress-nginx-controller 日志
[root@k8smaster ~]# kubectl log -f ingress-nginx-controller-69d84f9c5f-vv9sb -n ingress-nginx
Error: unknown command "log" for "kubectl"
Did you mean this?
top
logs
Run 'kubectl --help' for usage.
[root@k8smaster ~]# kubectl logs -f ingress-nginx-controller-69d84f9c5f-vv9sb -n ingress-nginx
-------------------------------------------------------------------------------
NGINX Ingress controller
Release: v1.1.1
Build: a17181e43ec85534a6fea968d95d019c5a4bc8cf
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.19.9
-------------------------------------------------------------------------------
W0319 05:20:50.050104 7 client_config.go:615] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0319 05:20:50.050214 7 main.go:223] "Creating API client" host="https://10.96.0.1:443"
I0319 05:20:50.064789 7 main.go:267] "Running in Kubernetes cluster" major="1" minor="22" git="v1.22.3" state="clean" commit="c92036820499fedefec0f847e2054d824aea6cd1" platform="linux/amd64"
I0319 05:20:50.226998 7 main.go:104] "SSL fake certificate created" file="/etc/ingress-controller/ssl/default-fake-certificate.pem"
I0319 05:20:50.242856 7 ssl.go:531] "loading tls certificate" path="/usr/local/certificates/cert" key="/usr/local/certificates/key"
I0319 05:20:50.270217 7 nginx.go:255] "Starting NGINX Ingress controller"
I0319 05:20:50.277940 7 event.go:282] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"ingress-nginx", Name:"ingress-nginx-controller", UID:"ca616501-792c-4f4b-95a3-453cd05cab36", APIVersion:"v1", ResourceVersion:"8881", FieldPath:""}): type: 'Normal' reason: 'CREATE' ConfigMap ingress-nginx/ingress-nginx-controller
I0319 05:20:51.472200 7 nginx.go:297] "Starting NGINX process"
I0319 05:20:51.472265 7 leaderelection.go:248] attempting to acquire leader lease ingress-nginx/ingress-controller-leader...
I0319 05:20:51.472626 7 nginx.go:317] "Starting validation webhook" address=":8443" certPath="/usr/local/certificates/cert" keyPath="/usr/local/certificates/key"
I0319 05:20:51.472776 7 controller.go:155] "Configuration changes detected, backend reload required"
I0319 05:20:51.480203 7 leaderelection.go:258] successfully acquired lease ingress-nginx/ingress-controller-leader
I0319 05:20:51.480368 7 status.go:84] "New leader elected" identity="ingress-nginx-controller-69d84f9c5f-vv9sb"
I0319 05:20:51.519115 7 controller.go:172] "Backend successfully reloaded"
I0319 05:20:51.519175 7 controller.go:183] "Initial sync, sleeping for 1 second"
I0319 05:20:51.519257 7 event.go:282] Event(v1.ObjectReference{Kind:"Pod", Namespace:"ingress-nginx", Name:"ingress-nginx-controller-69d84f9c5f-vv9sb", UID:"84dfa8f2-de4b-4191-872b-8599510919f3", APIVersion:"v1", ResourceVersion:"9612", FieldPath:""}): type: 'Normal' reason: 'RELOAD' NGINX reload triggered due to a change in configuration
I0319 06:07:33.859343 7 admission.go:149] processed ingress via admission controller {testedIngressLength:1 testedIngressTime:0.024s renderingIngressLength:1 renderingIngressTime:0s admissionTime:18.0kBs testedConfigurationSize:0.024}
I0319 06:07:33.859366 7 main.go:101] "successfully validated configuration, accepting" ingress="test/ingress-service"
I0319 06:07:33.863734 7 store.go:420] "Ignoring ingress because of error while validating ingress class" ingress="test/ingress-service" error="ingress does not contain a valid IngressClass"
# 错误 ingress does not contain a valid IngressClass
ingress does not contain a valid IngressClass
除了可能会有多个不同类型的 Ingress Controller 之外,还可能存在多个相同类型的 Ingress Controller,比如部署了两个 NGINX Ingress Controller,一个负责处理外网访问,一个负责处理内网访问。
此时也可以通过上面的方式,为每个 Controller 设定唯一的一个 class。
当多个 controller 的 class 不唯一,或者 controller 和 Ingress 都没有指定 class 又没有默认的 class 时,会导致所有符合条件的 Ingress Controller 竞争满足 Ingress 配置,可能会导致不可预测的结果。
创建ingress 添加 IngressClass属性
查看 IngressClass
[root@k8smaster ingress]# kubectl get ingressClass
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx 3h50m
修改我们的service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-service
namespace: test
spec:
# 这一步需要指定ingressClassName,不然信息无法同步到nginx配置中,也会报 ingress does not contain a valid Ingress Class 错误
ngressClassName: nginx
rules:
- host: www.ixx.com # 自定义的域名
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: test-ingress # 上面创建的服务名 svc
port:
number: 80
重新应用
[root@k8smaster ingress]# vim test-ingress.yml
[root@k8smaster ingress]# kubectl apply -f test-ingress.yml
ingress.networking.k8s.io/ingress-service configured
设置默认的 IngressClass 注意:修改后必须新创建的ingress才会默认使用
在集群中,我们可以设定一个默认的 Ingress Class,以便处理所有没有指定 Ingress Class 的 Ingress 资源。
在 IngressClass
资源上,我们可以通过将 ingressclass.kubernetes.io/is-default-class
注解的值设定为 true
,来使没有设置 ingressClassName
的 Ingress 使用此默认的 IngressClass
。
注意:当存在多个默认 Ingress Class 时,新的 Ingress 如果没有指定
ingressClassName
则不会被允许创建。解决这个问题只需确保集群中最多只能有一个 IngressClass 被标记为默认。