目录
实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.22.2
containerd://1.5.5
3、helm:v3.7.2
4、ingress-nginx:v4.1.0
实验软件
链接:https://pan.baidu.com/s/1WbnzTI3II7X3jGyCKDN3GQ?pwd=83ol 提取码:83ol
前置条件
基础知识
🍀 注意:部署成deployment和daemonset有什么区别?
假如说你的Ingress想要部署成多个副本,或者说是部署在多个节点上面,那么的话,肯定用daemonset形式。
因为你这个Ingress-nignx只需要一个节点部署一个副本就可以啊,你给他部署多个有什么意义吗?而且我们这里准备使用hostnetwork模式,因为你hostNetwork模式,你一个节点能部署多个副本吗?肯定不行的啦。如果你部署超过一个节点以上,那你就用daemonset模式吧。
本次使用daemonset 方式部署。
🍀 注意:本次使用hostwork模式
由于 ingress-nginx 所在的节点需要能够访问外网,这样域名可以解析到这些节点上直接使用。所以需要让 ingress-nginx 绑定节点的 80 和 443 端口,所以可以使用 hostPort (hostwork也是可以的)来进行访问。当然对于线上环境来说为了保证高可用,一般是需要运行多个ingress-nginx 实例的,然后可以用一个 nginx/haproxy 作为入口,通过 keepalived 来访问边缘节点的 vip 地址。
?? 边缘节点:所谓的边缘节点即集群内部用来向集群外暴露服务能力的节点,集群外部的服务通过该节点来调用集群内部的服务,边缘节点是集群内外交流的一个 Endpoint。
我这里是打算只在master1节点上部署ingress-nginx。如果我想在node1和node2个节点行部署ingress-nginx的话,可以给这2个节点打上个label,例如 role=lb ,然后只需要把这个label写到 nodeSelector 下面就好。
我们这里测试环境就将 master1 节点看成边缘节点,所以我们就直接将 ingress-nginx 固定到 master1 节点上,采用 hostNetwork 模式(生产环境可以使用 LB + DaemonSet hostNetwork 模式)。
注意:当然你有多个边缘节点的话,可以对这些边缘节点打上一个label,然后把ingress-nginx给固定到上面去,然后采用hostNetwork模式。
🍀 注意:推荐开启准入控制器
为了避免创建的错误 Ingress 等资源对象影响控制器重新加载,所以我们也强烈建议大家开启准入控制器,ingess-nginx 中会提供一个用于校验资源对象的 Admission Webhook,我们可以通过 Values 文件进行开启。设置成true之后,当我们去创建Ingress资源对象的时候,它会用这里的admission Webhooks去做一个校验,就是你不是一个正确的Ingress资源对象的话,那它就会拒绝掉。那你拒绝掉之后,我们这个Ingress-controller它就不会去重新加载了,或多或少它可以它可以避免控制器重新加载之类的情况。
[root@master1 ci]#/root/ingress-nginx/ci/deployment-webhook-values.yaml
1、helm方式安装ingress-nginx
这里我们使用 Helm Chart的方式来进行安装:
🍀 关于helm如何安装,请查看我的文档:
实战:helm包管理-2022.4.4:https://blog.csdn.net/weixin_39246554/article/details/123955289
? helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
? helm repo update
? helm fetch ingress-nginx/ingress-nginx
? tar -xvf ingress-nginx-4.1.0.tgz && cd ingress-nginx
? tree .
.
├── CHANGELOG.md
├── Chart.yaml
├── OWNERS
├── README.md
├── ci
│ ├── controller-custom-ingressclass-flags.yaml
│ ├── daemonset-customconfig-values.yaml
│ ├── daemonset-customnodeport-values.yaml
│ ├── daemonset-headers-values.yaml
│ ├── daemonset-internal-lb-values.yaml
│ ├── daemonset-nodeport-values.yaml
│ ├── daemonset-podannotations-values.yaml
│ ├── daemonset-tcp-udp-configMapNamespace-values.yaml
│ ├── daemonset-tcp-udp-values.yaml
│ ├── daemonset-tcp-values.yaml
│ ├── deamonset-default-values.yaml
│ ├── deamonset-metrics-values.yaml
│ ├── deamonset-psp-values.yaml
│ ├── deamonset-webhook-and-psp-values.yaml
│ ├── deamonset-webhook-values.yaml
│ ├── deployment-autoscaling-behavior-values.yaml
│ ├── deployment-autoscaling-values.yaml
│ ├── deployment-customconfig-values.yaml
│ ├── deployment-customnodeport-values.yaml
│ ├── deployment-default-values.yaml
│ ├── deployment-headers-values.yaml
│ ├── deployment-internal-lb-values.yaml
│ ├── deployment-metrics-values.yaml
│ ├── deployment-nodeport-values.yaml
│ ├── deployment-podannotations-values.yaml
│ ├── deployment-psp-values.yaml
│ ├── deployment-tcp-udp-configMapNamespace-values.yaml
│ ├── deployment-tcp-udp-values.yaml
│ ├── deployment-tcp-values.yaml
│ ├── deployment-webhook-and-psp-values.yaml
│ ├── deployment-webhook-resources-values.yaml
│ └── deployment-webhook-values.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── _params.tpl
│ ├── admission-webhooks
│ │ ├── job-patch
│ │ │ ├── clusterrole.yaml
│ │ │ ├── clusterrolebinding.yaml
│ │ │ ├── job-createSecret.yaml
│ │ │ ├── job-patchWebhook.yaml
│ │ │ ├── psp.yaml
│ │ │ ├── role.yaml
│ │ │ ├── rolebinding.yaml
│ │ │ └── serviceaccount.yaml
│ │ └── validating-webhook.yaml
│ ├── clusterrole.yaml
│ ├── clusterrolebinding.yaml
│ ├── controller-configmap-addheaders.yaml
│ ├── controller-configmap-proxyheaders.yaml
│ ├── controller-configmap-tcp.yaml
│ ├── controller-configmap-udp.yaml
│ ├── controller-configmap.yaml
│ ├── controller-daemonset.yaml
│ ├── controller-deployment.yaml
│ ├── controller-hpa.yaml
│ ├── controller-ingressclass.yaml
│ ├── controller-keda.yaml
│ ├── controller-poddisruptionbudget.yaml
│ ├── controller-prometheusrules.yaml
│ ├── controller-psp.yaml
│ ├── controller-role.yaml
│ ├── controller-rolebinding.yaml
│ ├── controller-service-internal.yaml
│ ├── controller-service-metrics.yaml
│ ├── controller-service-webhook.yaml
│ ├── controller-service.yaml
│ ├── controller-serviceaccount.yaml
│ ├── controller-servicemonitor.yaml
│ ├── default-backend-deployment.yaml
│ ├── default-backend-hpa.yaml
│ ├── default-backend-poddisruptionbudget.yaml
│ ├── default-backend-psp.yaml
│ ├── default-backend-role.yaml
│ ├── default-backend-rolebinding.yaml
│ ├── default-backend-service.yaml
│ ├── default-backend-serviceaccount.yaml
│ └── dh-param-secret.yaml
└── values.yaml
4 directories, 81 files
Helm Chart 包下载下来后解压就可以看到里面包含的模板文件,其中的 ci 目录中就包含了各种场景下面安装的 Values 配置文件,values.yaml 文件中包含的是所有可配置的默认值,我们可以对这些默认值进行覆盖。
?? 注意:如果你不喜欢使用 helm chart 进行安装也可以使用下面的命令一键安装
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/cloud/deploy.yaml
2、创建自定义Values.yaml文件
然后新建一个名为 ci/daemonset-prod.yaml 的 Values 文件,用来覆盖 ingress-nginx 默认的 Values 值。
注意:以下配置参数不是随便设置的,一定要是values.yaml里面有的才可以的哦;
[root@master1 ingress-nginx]#vim ci/daemonset-prod.yaml
controller:
name: controller
image:
repository: cnych/ingress-nginx
tag: "v1.1.0"
digest:
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
publishService:
enabled: false
watchIngressWithoutClass: false
kind: DaemonSet
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Equal"
effect: "NoSchedule"
nodeSelector:
kubernetes.io/hostname: master1
service:
enabled: false
admissionWebhooks:
enabled: true
createSecretJob:
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
patchWebhookJob:
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi
patch:
enabled: true
image:
repository: cnych/ingress-nginx-webhook-certgen
tag: v1.1.1
digest:
defaultBackend:
enabled: true
name: defaultbackend
image:
repository: cnych/ingress-nginx-defaultbackend
tag: "1.5"
3、安装
然后使用如下命令安装 ingress-nginx 应用到 ingress-nginx 的命名空间中:
[root@master1 ingress-nginx]
Release "ingress-nginx" has been upgraded. Happy Helming!
NAME: ingress-nginx
LAST DEPLOYED: Tue Apr 26 21:05:04 2022
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace ingress-nginx get services -o wide -w ingress-nginx-controller'
An example Ingress that makes use of the controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: foo
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- pathType: Prefix
backend:
service:
name: exampleService
port:
number: 80
path: /
tls:
- hosts:
- www.example.com
secretName: example-tls
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
4、验证
[root@master1 ingress-nginx]
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-r5964 1/1 Running 0 8m2s 172.29.9.51 master1 <none> <none>
ingress-nginx-defaultbackend-84854cd6cb-8gzcm 1/1 Running 0 8m2s 10.244.1.197 node1 <none> <none>
[root@master1 ingress-nginx]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller-admission ClusterIP 10.106.208.0 <none> 443/TCP 8m8s
ingress-nginx-defaultbackend ClusterIP 10.106.66.15 <none> 80/TCP 8m8s
[root@master1 ingress-nginx]
[root@master1 ingress-nginx]
ingress-nginx-controller-r5964
[root@master1 ingress-nginx]
-------------------------------------------------------------------------------
NGINX Ingress controller
Release: v1.1.0
Build: cacbee86b6ccc45bde8ffc184521bed3022e7dee
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.19.9
-------------------------------------------------------------------------------
W0426 13:00:16.359192 7 client_config.go:615] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
I0426 13:00:16.359981 7 main.go:223] "Creating API client" host="https://10.96.0.1:443"
I0426 13:00:16.387442 7 main.go:267] "Running in Kubernetes cluster" major="1" minor="22" git="v1.22.2" state="clean" commit="8b5a19147530eaac9476b0ab82980b4088bbc1b2" platform="linux/amd64"
I0426 13:00:16.400163 7 main.go:86] "Valid default backend" service="ingress-nginx/ingress-nginx-defaultbackend"
I0426 13:00:16.615214 7 main.go:104] "SSL fake certificate created" file="/etc/ingress-controller/ssl/default-fake-certificate.pem"
I0426 13:00:16.704300 7 ssl.go:531] "loading tls certificate" path="/usr/local/certificates/cert" key="/usr/local/certificates/key"
I0426 13:00:16.752208 7 nginx.go:255] "Starting NGINX Ingress controller"
I0426 13:00:16.785466 7 event.go:282] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"ingress-nginx", Name:"ingress-nginx-controller", UID:"8e41333d-a6e7-47d6-a8e8-b1d0dab0fda7", APIVersion:"v1", ResourceVersion:"2336338", FieldPath:""}): type: 'Normal' reason: 'CREATE' ConfigMap ingress-nginx/ingress-nginx-controller
I0426 13:00:17.963766 7 store.go:424] "Found valid IngressClass" ingress="default/ghost" ingressclass="nginx"
I0426 13:00:17.965404 7 event.go:282] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"ghost", UID:"b421eee9-26f3-43a2-8d07-08df3c9fd814", APIVersion:"networking.k8s.io/v1", ResourceVersion:"2321677", FieldPath:""}): type: 'Normal' reason: 'Sync' Scheduled for sync
I0426 13:00:18.055029 7 nginx.go:297] "Starting NGINX process"
I0426 13:00:18.055380 7 leaderelection.go:248] attempting to acquire leader lease ingress-nginx/ingress-controller-leader...
I0426 13:00:18.061064 7 status.go:84] "New leader elected" identity="ingress-nginx-controller-dm4bg"
I0426 13:00:18.061232 7 nginx.go:317] "Starting validation webhook" address=":8443" certPath="/usr/local/certificates/cert" keyPath="/usr/local/certificates/key"
I0426 13:00:18.062097 7 controller.go:155] "Configuration changes detected, backend reload required"
I0426 13:00:18.177454 7 controller.go:172] "Backend successfully reloaded"
I0426 13:00:18.177565 7 controller.go:183] "Initial sync, sleeping for 1 second"
I0426 13:00:18.177972 7 event.go:282] Event(v1.ObjectReference{Kind:"Pod", Namespace:"ingress-nginx", Name:"ingress-nginx-controller-r5964", UID:"edd71a4c-5f9d-4b3c-aa8e-b45ef67472ef", APIVersion:"v1", ResourceVersion:"2336371", FieldPath:""}): type: 'Normal' reason: 'RELOAD' NGINX reload triggered due to a change in configuration
I0426 13:00:57.356030 7 leaderelection.go:258] successfully acquired lease ingress-nginx/ingress-controller-leader
I0426 13:00:57.356251 7 status.go:84] "New leader elected" identity="ingress-nginx-controller-r5964"
当看到上面的信息证明 ingress-nginx 部署成功了,这里我们安装的是最新版本的控制器。
- 安装完成后会自动创建一个名为
nginx 的 IngressClass 对象:
[root@master1 ingress-nginx]
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 12m
[root@master1 ingress-nginx]
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
annotations:
meta.helm.sh/release-name: ingress-nginx
meta.helm.sh/release-namespace: ingress-nginx
creationTimestamp: "2022-04-26T13:00:15Z"
generation: 1
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
helm.sh/chart: ingress-nginx-4.1.0
name: nginx
resourceVersion: "2336359"
uid: 52bf2d88-a0d4-48e4-bb25-e07c7ae05375
spec:
controller: k8s.io/ingress-nginx
不过这里我们只提供了一个 controller 属性,如果还需要配置一些额外的参数,则可以在安装的 values 文件中进行配置。
5、第一个示例
- 安装成功后,现在我们来为一个 nginx 应用创建一个 Ingress 资源,如下所示:
[root@master1 ingress]#vim first-ingress.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: my-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-nginx
namespace: default
spec:
ingressClassName: nginx
rules:
- host: ngdemo.qikqiak.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-nginx
port:
number: 80
[root@master1 ingress-nginx]
deployment.apps/my-nginx created
service/my-nginx created
ingress.networking.k8s.io/my-nginx created
[root@master1 ingress-nginx]
NAME READY STATUS RESTARTS AGE
my-nginx-7c4ff94949-hrxbh 1/1 Running 0 70s
[root@master1 ingress-nginx]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 177d
my-nginx ClusterIP 10.101.20.210 <none> 80/TCP 72s
记得在本地pc里配置下域名解析:
C:\WINDOWS\System32\drivers\etc
172.29.9.51 ngdemo.qikqiak.com
[root@master1 ingress-nginx]
NAME CLASS HOSTS ADDRESS PORTS AGE
my-nginx nginx ngdemo.qikqiak.com 172.29.9.51 80 2m19s
在上面的 Ingress 资源对象中我们使用配置 ingressClassName: nginx 指定让我们安装的 ingress-nginx 这个控制器来处理我们的 Ingress 资源,配置的匹配路径类型为前缀的方式去匹配 / ,将来自域名 ngdemo.qikqiak.com 的所有请求转发到 my-nginx 服务的后端 Endpoints 中去。
上面资源创建成功后,然后我们可以将域名 ngdemo.qikqiak.com 解析到 ingress-nginx 所在的边缘节点中的任意一个,当然也可以在本地 /etc/hosts 中添加对应的映射也可以,然后就可以通过域名进行访问了。
(本地测试这里直接配置了hosts,但线上的还一般就是用dns了)
http://ngdemo.qikqiak.com/
🍀 详细看下其中流程
下图显示了客户端是如何通过 Ingress 控制器连接到其中一个 Pod 的流程,客户端首先对 ngdemo.qikqiak.com 执行 DNS 解析,得到 Ingress 控制器所在节点的 IP,然后客户端向 Ingress 控制器发送 HTTP 请求,然后根据 Ingress 对象里面的描述匹配域名,找到对应的 Service 对象,并获取关联的 Endpoints 列表,将客户端的请求转发给其中一个 Pod。
前面我们也提到了 ingress-nginx 控制器的核心原理就是将我们的 Ingress 这些资源对象映射翻译成 Nginx 配置文件 nginx.conf ,我们可以通过查看控制器中的配置文件来验证这点:
[root@master1 ingress]
......
upstream upstream_balancer {
server 0.0.0.1;
balancer_by_lua_block {
balancer.balance()
}
keepalive 320;
keepalive_timeout 60s;
keepalive_requests 10000;
}
......
server {
server_name ngdemo.qikqiak.com ;
listen 80 ;
listen [::]:80 ;
listen 443 ssl http2 ;
listen [::]:443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
location / {
set $namespace "default";
set $ingress_name "my-nginx";
set $service_name "my-nginx";
set $service_port "80";
set $location_path "/";
set $global_rate_limit_exceeding n;
......
proxy_next_upstream_timeout 0;
proxy_next_upstream_tries 3;
proxy_pass http://upstream_balancer
proxy_redirect off;
}
}
......
我们可以在 nginx.conf 配置文件中看到上面我们新增的 Ingress 资源对象的相关配置信息,不过需要注意的是:现在并不会为每个 backend 后端都创建一个 upstream 配置块,现在是使用 Lua 程序进行动态处理的,所以我们没有直接看到后端的 Endpoints 相关配置数据(以前的版本是可以看到的)。
?? 注意:
upstream里面可以配置很多的负载策略,并且可以让nginx去帮我们做一个可定制的负载(如果是走service的话,那负载策略就是service说了算的了);
关于我
我的博客主旨:我希望每一个人拿着我的博客都可以做出实验现象,先把实验做出来,然后再结合理论知识更深层次去理解技术点,这样学习起来才有乐趣和动力。并且,我的博客内容步骤是很完整的,也分享源码和实验用到的软件,希望能和大家一起共同进步!
各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人免费帮您解决问题:
-
个人微信二维码:x2675263825 (舍得), qq:2675263825。 -
个人微信公众号:《云原生架构师实战》 -
个人csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421 -
个人已开源干货😘 不服来怼:宇宙中最好用的云笔记 & 其他开源干货:https://www.yuque.com/go/doc/73723298?# -
知乎 https://www.zhihu.com/people/foryouone -
个人网站:(计划ing)
最后
好了,关于ingress-nginx安装实验就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见! 75263825。
[外链图片转存中…(img-3z3URFLN-1650983153254)]
-
个人微信公众号:《云原生架构师实战》 [外链图片转存中…(img-UfASeZhZ-1650983153255)] -
个人csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421 [外链图片转存中…(img-ZZcnyRO0-1650983153256)] -
个人已开源干货😘 不服来怼:宇宙中最好用的云笔记 & 其他开源干货:https://www.yuque.com/go/doc/73723298?# [外链图片转存中…(img-uVta6nQj-1650983153257)] [外链图片转存中…(img-OWuSheLy-1650983153258)] -
知乎 https://www.zhihu.com/people/foryouone [外链图片转存中…(img-NwCf3Uia-1650983153258)] -
个人网站:(计划ing)
最后
好了,关于ingress-nginx安装实验就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!
|