k8s容器编排技术实践------k8s应用中机密信息的配置与存储
https://blog.csdn.net/xiaochenXIHUA/article/details/161706954?spm=1001.2014.3001.5501k8s容器编排技术实践------k8s的介绍及其整体运行架构-CSDN博客
https://coffeemilk.blog.csdn.net/article/details/161011629
一、ingress-nginx简介
1.1、Service机制的局限性
| ⚠️Service机制的局限性 |
|---|
| 只提供 4 层负载均衡,不支持7层负载均衡功能。 |
| 使用 NodePort 类型的 Service,需要在集群外部部署一个外部的负载均衡器。 |
| 使用 LoadBalancer类型的Service,Kubernetes 必须运行在特定的云服务上。 |
| 每创建一个Service NodePort类型,就会在每个节点开启一个端口,当项目多时,端口会难以维护。当项目很多时,Service的Iptables规则也随着数倍增多,如此多的iptables条目让增大维护和故障定位。 |
如何理解上面的局限性呢,如下是NodePort模式运行原理图:

1.2、ingress-nginx如何实现服务发现
针对上述问题,k8s官方提供了一种折中的方案:Ingress与Service不同,Ingress实际上不是一种服务。相反,它位于多个服务之前,充当集群中的智能路由器或入口点。ingress-nginx实现架构如下图所示:

Ingress是在Kubernetes 1.1 版本后引入的资源类型。Ingress 支持将 Service 暴露到 Kubernetes 集群外,同时可以自定义 Service 的访问策略。Ingress 能够把 Service 配置成外网能够访问的 URL,也支持提供按域名访问的虚拟主机功能(如:通过负载均衡器实现不同的二级域名到不同 Service 的访问)。
实际上 Ingress 只是一个统称,主要有【Ingress】、【Ingress Controller】和【Ingress-Controller-service】三部分组成。
| Ingress构成 | 说明 |
|---|---|
| Ingress | 将原来需要手动配置的规则抽象成一个Ingress对象,使用YAML格式的文件来创建和管理。将请求转发给Ingress Controller。 |
| Ingress Controller | 核心组件,用作通过与Kubernetes API交互,动态感知集群中Ingress规则变化,并应用新配置,实现七层转发。 |
| Ingress-Controller-service | kuberntes中四层的负载均衡调度机制,Ingress借助service的服务发现机制实现集群中Pod资源的动态感知,用于接入外部流量; |
Ingress Controller目前有多种软件负载均衡实现(如:Nginx、HAProxy等),而本文要讲解的是基于Nginx的Ingress Controller。在使用 Ingress前必须要先部署 Ingress Controller,Ingress Controller是以一种插件的形式提供。Ingress Controller通常是部署在每个Node上,是一个pod服务,由Kubernetes管理,而不是我们单独部署。
以Ingress Nginx为例(Ingress Controller镜像包含一个Nginx service和一个Ingress Controller)。Ingress Controller会从apiserver获取到Ingress配置,然后动态生成nginx.conf配置文件,并重载(-s reload)配置。
1.3、ingress-nginx工作流程解析
| ingress-nginx工作流程 | 说明 |
|---|---|
| ingress | 简单理解:就是你原来需要修改nginx配置,然后配置各种域名对应哪个Service,现在把这个动作抽象出来,变成一个Ingress对象,你可以用yaml创建,每次不用去修改nginx了,直接改yaml然后创建/更新就行了,那么问题又来了:nginx该如何处理呢? |
| ingress controller | ingress controller就是解决nginx如何处理这个问题的,ingress controller通过与kubernetes API交互,动态的去感知集群中Ingress规则变化,然后读取它,按照它自己的模板生成一段nginx配置,再写到nginx Pod中,最后reload以下,工作流程如下图: 1. 首先有一个外部的负载均衡器externalLB把请求调度到一个nodePort类型的Service(ingress-nginx)上; 2. 然后nodePort类型的Service(ingress-nginx)又把它调度到内部的叫做ingressController的Pod上; 3. ingress Ctroller根据ingress中的定义(虚拟主机还是URL),每一组主机名或者URL都对应后端的Pod资源,并且用Service分组。 |

二、部署ingress-nginx服务
2.1、部署ingress-nginx服务的三种方法
2.1.1、Deployment+LoadBalancer模式的Service
如果要把ingress部署在【公有云】,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露。
2.1.2、Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境,并且IP地址不变的场景。
注意:NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。
2.1.3、DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点(如:机房入口的nginx服务器)。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。此方案比较适合大并发的生产环境使用。
2.2、Deployment+NodePort模式使用ingress-nginx
2.2.1、下载并部署ingress资源
首先需要下载ingress相关yaml文件,在nginx controller 0.30.0以及版本之前,需要下载多个yml文件(如:mandatory.yaml、service-nodeport.yaml等)。但在最新nginx controller版本中,这些部署文件合并到一个文件中了,从ingress-nginx/deploy/static/provider/baremetal at main · kubernetes/ingress-nginx · GitHub 下载deploy.yaml文件,这里使用的是最新版本,nginx controller版本为1.15.1,下载后,需要做几个简单修改【即:将registry.k8s.io修改为国内可用的k8s.m.daocloud.io】。

bash
#使用DaoCloud代理替换(推荐)
sed -i 's|registry.k8s.io|k8s.m.daocloud.io|g' deploy.yaml
# 或者使用阿里云镜像替换【备选】
sed -i 's|registry.k8s.io/ingress-nginx/controller|registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller|g' deploy.yaml
sed -i 's|registry.k8s.io/ingress-nginx/kube-webhook-certgen|registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen|g' deploy.yaml
#ingress-nginx资源部署
kubectl apply -f deploy.yaml
#查看指定的ingress-nginx的pod资源状态(必须是running;且READY必须是1/1才表示成功)
kubectl -n ingress-nginx get pod
#查看指定的ingress-nginx的pod日志信息
kubectl -n ingress-nginx logs ingress-nginx-controller-5d98f55d49-xtgw4
#查看指定ingress-nginx的所有service
kubectl -n ingress-nginx get svc
#查看指定ingress-nginx的service的详细信息
kubectl -n ingress-nginx describe svc ingress-nginx-controller

2.2.2、配置部署业务服务资源
即需要配置部署业务所需的deployment及其对应的service资源。
k8s容器编排技术实践------k8s对象job应用详解
https://blog.csdn.net/xiaochenXIHUA/article/details/161572905
k8s容器编排技术实践------K8s对象deployment应用详解
https://coffeemilk.blog.csdn.net/article/details/161427275
k8s容器编排技术实践------k8s对象service应用详解
https://coffeemilk.blog.csdn.net/article/details/161593299
bash
#创建httpd的pod及其service
#一、创建httpd的deployment资源
#1.1-创建资源文件httpd-deployment.yml
cat > httpd-deployment.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
spec:
replicas: 3
selector:
matchLabels:
app: httpd_server
template:
metadata:
labels:
app: httpd_server
spec:
containers:
- name: httpd-web
image: library/httpd:2.4.67
ports:
- containerPort: 80
EOF
#1.2-创建指定资源
kubectl apply -f httpd-deployment.yml
#1.3查看当前所有pod状态
kubectl get pod
#二、创建对应如上httpd-deployment.yml资源的service
#2.1-创建指定deployment的service资源文件httpd-service.yml
cat >httpd-service.yml<<EOF
apiVersion: v1
kind: Service
metadata:
name: httpd-service
spec:
type: NodePort
selector:
app: httpd_server
ports:
- protocol: TCP
port: 80
nodePort: 30060
targetPort: 80
EOF
#2.2-创建指定的资源文件
kubectl apply -f httpd-service.yml
#2.3-查看当前所有的service
kubectl get svc
bash
#创建nginx的pod及其service
#一、创建nginx的deployment资源
#1.1-创建资源文件nginx-deployment.yml
cat > nginx-deployment.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx_server
template:
metadata:
labels:
app: nginx_server
spec:
containers:
- name: nginx-web
image: library/nginx:1.28.3
ports:
- containerPort: 80
EOF
#1.2-创建指定资源
kubectl apply -f nginx-deployment.yml
#1.3查看当前所有pod状态
kubectl get pod -o wide
#二、创建对应如上nginx-deployment.yml资源的service
#2.1-创建指定nginx的service资源文件nginx-service.yml
cat >nginx-service.yml<<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx_server
ports:
- protocol: TCP
port: 80
targetPort: 80
EOF
#2.2-创建指定的资源文件
kubectl apply -f nginx-service.yml
#2.3-查看当前所有的service
kubectl get svc
#2.4-使用curl连接httpd-service与nginx-service
curl 10.97.0.199
curl 10.104.53.148



2.2.3、创建ingress服务
bash
#创建一个ingress服务,让外部可以通过域名来访问pod
cat>ingress-demo.yml<<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo
spec:
ingressClassName: nginx
rules:
- host: www.ck.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- host: www.ck1.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpd-service
port:
number: 80
EOF
#创建指定的资源
kubectl apply -f ingress-demo.yml
#查看ingress-nginx命名空间下的所有Service
kubectl get svc -n ingress-nginx
#配置本地域名解析(即:在本地域名解析文件中添加k8s集群中的任意节点IP 配置的pod域名)
#windows系统的本地域名解析文件是【C:\Windows\System32\drivers\etc\hosts】
#linux系统的本地域名解析文件是【/etc/hosts】
192.168.1.142 www.ck.com
192.168.1.142 www.ck1.com
#或者
192.168.1.140 www.ck.com
192.168.1.140 www.ck1.com
#或者
192.168.1.141 www.ck.com
192.168.1.141 www.ck1.com
#或者
192.168.1.143 www.ck.com
192.168.1.143 www.ck1.com
#浏览器直接访问【域名:ingress-nginx-controller端口】
http://www.ck.com:31992/
http://www.ck1.com:31992/






如上图正确显示不同pod组的service内容,则表示ingress-nginx配置成功!
注意:由于在配置本地域名解析时可以使用k8s集群中的任意节点IP,因此建议在ingress外层再添加一个nginx做负载均衡,这会造成一定的性能损耗。
Nginx中的内置变量、指令、URL重写功能及其虚拟主机配置、负载均衡配置
https://blog.csdn.net/xiaochenxihua/article/details/151138716

bash
#最终测试完成通过后,删除命令如下
kubectl delete -f ingress-demo.yml
kubectl delete -f deploy.yaml
#查看是否删除完成(显示"No resources found in ingress-nginx namespace."则表示删除完成)
kubectl -n ingress-nginx get pod
kubectl -n ingress-nginx get svc

2.3、DaemonSet+HostNetwork+nodeSelector模式使用ingress-nginx
2.3.1、下载并部署ingress资源
首先需要下载ingress相关yaml文件,在nginx controller 0.30.0以及版本之前,需要下载多个yml文件(如:mandatory.yaml、service-nodeport.yaml等)。但在最新nginx controller版本中,这些部署文件合并到一个文件中了,从ingress-nginx/deploy/static/provider/baremetal at main · kubernetes/ingress-nginx · GitHub 下载deploy.yaml文件,这里使用的是最新版本,nginx controller版本为1.15.1,下载后,需要做几个简单修改【即:将registry.k8s.io修改为国内可用的k8s.m.daocloud.io】。

bash
#需要对deploy.yaml文件修改
#1-使用DaoCloud代理替换(推荐)
sed -i 's|registry.k8s.io|k8s.m.daocloud.io|g' deploy.yaml
# 或者使用阿里云镜像替换【备选】
sed -i 's|registry.k8s.io/ingress-nginx/controller|registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller|g' deploy.yaml
sed -i 's|registry.k8s.io/ingress-nginx/kube-webhook-certgen|registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen|g' deploy.yaml
#2-在deployment资源部分,修改名为ingress-nginx-controller的Deployment类型为DaemonSet
kind: DaemonSet
#3-接着在此DaemonSet中的template下的spec中添加如下内容:
#3.1-修改spec下的strategy为updateStrategy
#3.2-这一步配置的操作是【添加网络模式和nodeselector标签,这样ingress-nginx-controller的pod就会部署到特定的node上,并且与宿主机的node网络也打通了,直接使用宿主机的80/433端口就能访问服务】且需要将最后的nodeSelector:kubernetes.io/os: linux注释或者直接修改为ingress: nginx-server。
hostNetwork: true
nodeSelector:
ingress: nginx-server
#4-给k8s集群中的任意节点(如:k8s-node1)设置ingress标签
kubectl label nodes k8s-node1 ingress=nginx-server
#5-查看当前所有的节点的标签状态
kubectl get node --show-labels
#创建资源
#ingress-nginx资源部署
kubectl apply -f deploy.yaml
#查看指定的ingress-nginx的daemonset资源状态(NODE状态必须是ingress=nginx-server)
kubectl -n ingress-nginx get daemonsets -o wide
#查看指定的ingress-nginx的pod资源状态(必须是running;READY必须是1/1;且IP必须是该节点所在的主机IP(如:192.168.1.142)而不是k8s的内部IP才表示成功)
kubectl -n ingress-nginx get pod -o wide
#查看指定的ingress-nginx的pod日志信息
kubectl -n ingress-nginx logs ingress-nginx-controller-5jzqh
#查看指定ingress-nginx的所有service
kubectl -n ingress-nginx get svc
#查看指定ingress-nginx的service的详细信息
kubectl -n ingress-nginx describe svc ingress-nginx-controller






2.3.2、配置部署业务服务资源
即需要配置部署业务所需的deployment及其对应的service资源。
bash
#创建httpd的pod及其service
#一、创建httpd的deployment资源
#1.1-创建资源文件httpd-deployment.yml
cat > httpd-deployment.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-deployment
spec:
replicas: 3
selector:
matchLabels:
app: httpd_server
template:
metadata:
labels:
app: httpd_server
spec:
containers:
- name: httpd-web
image: library/httpd:2.4.67
ports:
- containerPort: 80
EOF
#1.2-创建指定资源
kubectl apply -f httpd-deployment.yml
#1.3查看当前所有pod状态
kubectl get pod
#二、创建对应如上httpd-deployment.yml资源的service
#2.1-创建指定deployment的service资源文件httpd-service.yml
cat >httpd-service.yml<<EOF
apiVersion: v1
kind: Service
metadata:
name: httpd-service
spec:
type: NodePort
selector:
app: httpd_server
ports:
- protocol: TCP
port: 80
nodePort: 30060
targetPort: 80
EOF
#2.2-创建指定的资源文件
kubectl apply -f httpd-service.yml
#2.3-查看当前所有的service
kubectl get svc
bash
#创建nginx的pod及其service
#一、创建nginx的deployment资源
#1.1-创建资源文件nginx-deployment.yml
cat > nginx-deployment.yml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx_server
template:
metadata:
labels:
app: nginx_server
spec:
containers:
- name: nginx-web
image: library/nginx:1.28.3
ports:
- containerPort: 80
EOF
#1.2-创建指定资源
kubectl apply -f nginx-deployment.yml
#1.3查看当前所有pod状态
kubectl get pod -o wide
#二、创建对应如上nginx-deployment.yml资源的service
#2.1-创建指定nginx的service资源文件nginx-service.yml
cat >nginx-service.yml<<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx_server
ports:
- protocol: TCP
port: 80
targetPort: 80
EOF
#2.2-创建指定的资源文件
kubectl apply -f nginx-service.yml
#2.3-查看当前所有的service
kubectl get svc
#2.4-使用curl连接httpd-service与nginx-service
curl 10.97.0.199
curl 10.104.53.148
2.3.3、创建ingress服务
bash
#创建一个ingress服务,让外部可以通过域名来访问pod
cat>ingress-demo.yml<<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-demo
spec:
ingressClassName: nginx
rules:
- host: www.ck.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- host: www.ck1.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: httpd-service
port:
number: 80
EOF
#创建指定的资源
kubectl apply -f ingress-demo.yml
#查看ingress的状态信息
kubectl get ingress
#查看指定ingress-nginx命名空间下的所有pod状态详情
kubectl -n ingress-nginx get pod -o wide
#查看ingress-nginx命名空间下的所有Service状态
kubectl -n ingress-nginx get svc
#配置本地域名解析(即:在本地域名解析文件中添加指定了标签名称的podIP与域名)
#windows系统的本地域名解析文件是【C:\Windows\System32\drivers\etc\hosts】
#linux系统的本地域名解析文件是【/etc/hosts】
192.168.1.142 www.ck.com
192.168.1.142 www.ck1.com
#浏览器直接访问【域名】
http://www.ck.com
http://www.ck1.com
#剖析《ingress-controller会动态加载ingress服务资源,而不用手动配置》
#1-查看指定ingress-nginx命名空间下的所有pod状态详情
kubectl -n ingress-nginx get pod -o wide
#2-进入ingress-nginx的pod容器中(默认就在/etc/nginx目录下直接查看nginx.conf文件是否包含ingress服务的网站域名配置,有则表示是动态配置上的)
kubectl exec -it -n ingress-nginx ingress-nginx-controller-5jzqh sh
#也就是说需要配置网站域名内容只需要修改ingress服务资源文件后重新创建即可!!!



如上图,通过不同的域名可以正确显示不同pod组的service内容,则表示ingress-nginx配置成功!


