前言
在 Kubernetes 集群中,管理外部服务的访问和流量路由至关重要。通过使用 Ingress 控制器,我们能够实现对外部服务的有效管理,配置灵活的路由规则,并实现负载均衡和流量控制。
目录
5.1 方式一:Deployment+LoadBalancer 模式的 Service
5.2 方式二:DaemonSet+HostNetwork+nodeSelector
5.3 方式三:Deployment+NodePort模式的Service
1. 方式二:DaemonSet+HostNetwork+nodeSelector
1.1 部署 ingress-controller pod 及相关资源
1.3 指定 nginx-ingress-controller 运行在 node02 节点
1.4 修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络
1.6 启动 nginx-ingress-controller
1.9 查看 nginx-ingress-controller
2. 方式三:Deployment+NodePort模式的Service
2.1 下载 nginx-ingress-controller 和 ingress-nginx 暴露端口配置文件
2.3 启动 nginx-ingress-controller
1. 创建 deployment、Service、Ingress Yaml 资源
3. 创建 deployment、Service、Ingress Yaml 资源
1. 生成用户密码认证文件,创建 secret 资源进行存储
service 的作用体现在两个方面:
Ingress 是 Kubernetes 中用于管理对集群内服务的外部访问的 API 对象。它允许您将 HTTP 和 HTTPS 路由流量到集群中的服务,通过定义规则,Ingress 可以将传入的请求路由到适当的服务。

外部访问内部图示:

在 Kubernetes 中,Pod 的 IP 地址和 service 的 ClusterIP 仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes 目前提供了以下几种方案:
将service暴露在节点网络上,NodePort背后就是Kube-Proxy,Kube-Proxy是沟通service网络、Pod网络和节点网络的桥梁。
测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理就是个灾难。因为每个端口只能是一种服务,端口范围只能是 30000-32767。
通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。受限于云平台,且通常在云平台部署LoadBalancer还需要额外的费用。
在service提交后,Kubernetes就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端。
service允许为其分配外部IP,如果外部IP路由到集群中一个或多个Node上,Service会被暴露给这些externalIPs。通过外部IP进入到集群的流量,将会被路由到Service的Endpoint上。
示例:
① 创建控制器定义容器,并对外暴露端口
- [root@master01 ingress]# kubectl create deployment app01 --image=nginx:1.14 --replicas=1 --port=80
- deployment.apps/app01 created
- [root@master01 ingress]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- app01-68d9b5486f-d6s4x 1/1 Running 0 3s
- [root@master01 ingress]# kubectl expose deployment app01 --port=80 --target-port=80
- service/app01 exposed
② 编辑 "app01" 的 Service 的配置文件
- [root@master01 ingress]# kubectl edit svc app01
- externalIPs:
- - 192.168.190.88

③ 查看 Service 列表
- [root@master01 ingress]# kubectl get svc
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- app01 ClusterIP 10.96.82.195 192.168.190.88 80/TCP 8m43s
④ 访问页面

只需一个或者少量的公网IP和LB,即可同时将多个HTTP服务暴露到外网,七层反向代理。
可以简单理解为service的service,它其实就是一组基于域名和URL路径,把用户的请求转发到一个或多个service的规则。
原始架构与 Ingress 对比:

原来ens33是service端去暴露端口的,安全性低、不易管理,会面临k8s端口不够用的问题。
NodePort 和 Ingress 是 Kubernetes 中用于公开服务的两种不同方式:
NodePort:
Ingress:
可以理解为 nginx 的配置文件。ingress是一个API对象,通过yaml文件来配置,ingress对象的作用是定义请求如何转发到service的规则,可以理解为配置模板。
ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS以及基于域名的反向代理。ingress要依靠 ingress-controller 来具体实现以上功能。
可以当做反向代理或者说是转发器。ingress-controller是具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
实际上负责实现 Ingress 规则并处理外部流量的组件。Ingress Controller 监视 Kubernetes API 中的 Ingress 资源变化,并根据这些资源的配置来配置后端负载均衡器、反向代理或其它网络设备,以实现外部访问服务的目的。
Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
总结:

(1)ingress-controller通过和 kubernetes APIServer 交互,动态的去感知集群中ingress规则变化;
(2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置;
(3)再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中;
(4)然后reload一下使配置生效。以此达到域名区分配置和动态更新的作用。

如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个 type为 LoadBalancer 的 service 关联这组 pod。大部分公有云,都会为 LoadBalancer 的 service 自动创建一个负载均衡器,通常还绑定了公网地址。 只要把域名解析指向该地址,就实现了集群服务的对外暴露。
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。 比较适合大并发的生产环境使用。
同样用deployment模式部署ingress-controller,并创建对应的service,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。
- [root@master01 ~]# mkdir /opt/ingress;cd /opt/ingress
- [root@master01 ingress]# ls
- mandatory.yaml
官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml上面可能无法下载,可用国内的 gitee
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。
- [root@master01 ingress]# vim mandatory.yaml
- 84 - apiGroups:
- 85 - "extensions"
- 86 - "networking.k8s.io" #(0.25版本)增加networking.k8s.io Ingress资源的api
-
- 100 - apiGroups:
- 101 - "extensions"
- 102 - "networking.k8s.io" #(0.25版本)增加networking.k8s.io/v1 Ingress资源的api
采用方式二:DaemonSet+HostNetwork+nodeSelector

- [root@master01 ingress]# kubectl label node node02 nj=zs
-
- [root@master01 ingress]# kubectl get nodes --show-labels
- NAME STATUS ROLES AGE VERSION LABELS
- master01 Ready control-plane,master 18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master01,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
- node01 NotReady
18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,fql=a,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux - node02 NotReady
18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,fql=b,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux,nj=zs
- [root@master01 ingress]# vim mandatory.yaml
- 191 kind: DaemonSet # 修改 kind
- 199 # replicas: 1 # 删除Replicas
- 212 spec:
- 213 hostNetwork: true # 使用主机网络
- 214 nodeSelector: # 选择节点运行
- 215 nj: zs
在所有 node02 节点上传 nginx-ingress-controller 镜像压缩包 ingree.contro.tar.gz 到 /opt/ingress 目录,并解压和加载镜像。
- [root@node02 data]# ls
- ingree.contro.tar.gz
- [root@node02 data]# tar xf ingree.contro.tar.gz
- [root@node02 data]# ls
- ingree.contro.tar ingree.contro.tar.gz
- [root@node02 data]# docker load -i ingree.contro.tar
- Loaded image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0
- [root@master01 ingress]# kubectl apply -f mandatory.yaml
- namespace/ingress-nginx created
- configmap/nginx-configuration created
- configmap/tcp-services created
- configmap/udp-services created
- serviceaccount/nginx-ingress-serviceaccount created
- Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
- clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
- Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Role
- role.rbac.authorization.k8s.io/nginx-ingress-role created
- Warning: rbac.authorization.k8s.io/v1beta1 RoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 RoleBinding
- rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
- Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
- clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
- daemonset.apps/nginx-ingress-controller created
① nginx-ingress-controller 已经运行 node02 节点
- [root@master01 ingress]# kubectl get pod -n ingress-nginx -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-ingress-controller-c5xfb 1/1 Running 0 11s 192.168.190.102 node02
- # 如果是0/1去node节点查看一下80端口是否有pod占用
-
- [root@node02 data]# netstat -antulp | grep :80
- tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 129841/nginx: mast
-
- [root@master01 ingress]# kubectl get cm,daemonset -n ingress-nginx -o wide
- NAME DATA AGE
- configmap/ingress-controller-leader-nginx 0 69s
- configmap/nginx-configuration 0 73s
- configmap/tcp-services 0 73s
- configmap/udp-services 0 73s
-
- NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
- daemonset.apps/nginx-ingress-controller 1 1 1 1 1 nj=zs 72s nginx-ingress-controller quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0 app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
② 到 node02 节点查看
- [root@node02 data]# netstat -lntp | grep nginx
- tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 129841/nginx: maste
- tcp 0 0 0.0.0.0:8181 0.0.0.0:* LISTEN 129841/nginx: maste
- tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 129841/nginx: maste
- tcp6 0 0 :::10254 :::* LISTEN 129805/nginx-ingre
由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。
这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了。如果要 nginx 高可用的话,可以在多个 node上部署,并在前面再搭建一套 LVS+keepalived 做负载均衡。
- [root@master01 ingress]# kubectl create deployment myapp-demo01 --image=nginx:1.14 --replicas=3 --port=80
- deployment.apps/myapp-demo01 created
- [root@master01 ingress]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- myapp-demo01-98f9b7bf7-kftxn 1/1 Running 0 2s
- myapp-demo01-98f9b7bf7-sgzfn 1/1 Running 0 2s
- myapp-demo01-98f9b7bf7-tsjvv 1/1 Running 0 2s
-
- [root@master01 ingress]# kubectl delete svc --all
-
- [root@master01 ingress]# kubectl expose deployment myapp-demo01 --port=80 --target-port=80
- service/myapp-demo01 exposed
- [root@master01 ingress]# kubectl get svc
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- myapp-demo01 ClusterIP 10.96.227.130
80/TCP 3s -
- [root@master01 ingress]# curl 10.96.227.130 -I
- HTTP/1.1 200 OK
到这里,四层转发已经没有问题了;接下来就是要把 ingress-controller 关联 service。即七层关联四层。
方法一:(extensions/v1beta1 Ingress 在1.22版本即将弃用)
- [root@master01 ingress]# vim ingress-app.yaml
- apiVersion: extensions/v1beta1
- kind: Ingress # 这是一个 Ingress 资源,用于定义对集群中服务的外部访问规则
- metadata: # 元数据
- name: nginx-app-ingress # 资源的名称
- spec: # 规定了 Ingress 资源的规格,包括访问规则
- rules: # 定义了访问规则,指定了如何路由到后端服务
- - host: www.aaa.com # 指定了这条规则适用于主机 www.aaa.com
- http: # 定义了 HTTP 访问规则
- paths: # 指定了路径匹配规则
- - path: / # 表示所有以 / 开头的路径都会匹配到这个规则,这里是网站的根路径
- backend: # 指定了后端服务的配置
- serviceName: myapp-demo01 # 后端服务的名称为 myapp-demo01,这是要将流量转发到的服务的名称
- servicePort: 80
方法二:
- [root@master01 ingress]# vim ingress-app01.yaml
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: nginx-app-ingress
- spec:
- rules: # 定义了访问规则,指定了如何路由到后端服务
- - host: www.aaa.com # 指定了这条规则适用于主机 www.aaa.com
- http: # 定义了 HTTP 访问规则
- paths: # 指定了路径匹配规则
- - path: / # 网站路径,所有以 / 开头的路径都会匹配到这个规则
- pathType: Prefix # 路径匹配,基于前缀;exect 完全匹配
- backend: # 指定了后端服务的配置
- service: # 定义了后端服务的名称和端口号
- name: myapp-demo01 # 后端服务的名称为 myapp-demo01,这是要将流量转发到的服务
- port:
- number: 80
启动 Ingress
- [root@master01 ingress]# kubectl apply -f ingress-app.yaml
- Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
- ingress.extensions/nginx-app-ingress created
- [root@master01 ingress]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- myapp-demo01-98f9b7bf7-kftxn 1/1 Running 0 12m
- myapp-demo01-98f9b7bf7-sgzfn 1/1 Running 0 12m
- myapp-demo01-98f9b7bf7-tsjvv 1/1 Running 0 12m
- [root@master01 ingress]# kubectl get ingress
- NAME CLASS HOSTS ADDRESS PORTS AGE
- nginx-app-ingress
www.aaa.com 80 28s
本地 host 添加域名解析:
[root@master01 ingress]# echo 192.168.190.102 www.aaa.com >> /etc/hosts
访问页面:
- [root@master01 ingress]# curl www.aaa.com -I
- HTTP/1.1 200 OK
- [root@master01 ingress]# kubectl get pod -n ingress-nginx -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx-ingress-controller-c5xfb 1/1 Running 0 32m 192.168.190.102 node02
-
- [root@master01 ingress]# kubectl exec -it nginx-ingress-controller-c5xfb -n ingress-nginx /bin/bash
- kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
- www-data@node02:/etc/nginx$ cat /etc/nginx/nginx.conf
- [root@master01 ingress]# kubectl delete -f ingress-app.yaml
- [root@master01 ingress]# kubectl delete -f mandatory.yaml
-
- [root@master01 ingress]# mkdir nodeport;cd nodeport
-
- 官方下载地址:
- wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
- wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
-
- 国内 gitee 资源地址:
- wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
- wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
-
- [root@master01 nodeport]# rz -E
- rz waiting to receive.
- [root@master01 nodeport]# ls
- ingress-nginx.yaml mandatory.yaml service-nodeport.yaml
在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar 到 /opt/ingress-nodeport 目录,并加载镜像。
- [root@node01 data]# rz -E
- rz waiting to receive.
- [root@node01 data]# ls
- ingree.contro-0.30.0.tar.gz
- [root@node01 data]# tar xf ingree.contro-0.30.0.tar.gz
- [root@node01 data]# ls
- ingree.contro-0.30.0.tar ingree.contro-0.30.0.tar.gz
- [root@node01 data]# docker load -i ingree.contro-0.30.0.tar
-
- [root@node02 data]# docker load -i ingree.contro-0.30.0.tar
- [root@master01 nodeport]# kubectl apply -f mandatory.yaml
- [root@master01 nodeport]# kubectl apply -f service-nodeport.yaml
-
- [root@master01 nodeport]# kubectl get svc,pod -n ingress-nginx
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- service/ingress-nginx NodePort 10.96.69.94
80:32269/TCP,443:32017/TCP 69s -
- NAME READY STATUS RESTARTS AGE
- pod/nginx-ingress-controller-54b86f8f7b-2gm9j 1/1 Running 0 100s
如果K8S Pod 调度失败,在 kubectl describe pod资源时显示:
Warning FailedScheduling 18s (x2 over 18s) default-scheduler 0/2 nodes are available: 2 node(s) didn't match node selector
解决方案:
① 给需要调度的node加上对应标签
# 相对上面这个Yaml文件的例子
kubectl label nodes node_name kubernetes.io/os=linux
② 删除Yaml文件中的nodeSelector,如果对节点没有要求的话,直接删除节点选择器即可
Ingress HTTP代理访问通常用于在Kubernetes集群中管理入站和出站流量。通过设置Ingress代理,可以实现对集群中部署的服务进行访问控制、负载均衡、SSL终止等功能。
- [root@master01 nodeport]# vim ingress-nginx.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx-app
- spec:
- replicas: 2
- selector:
- matchLabels:
- name: nginx
- template:
- metadata:
- labels:
- name: nginx
- spec:
- containers:
- - name: nginx
- image: nginx
- imagePullPolicy: IfNotPresent
- ports:
- - containerPort: 80
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: nginx-svc
- spec:
- ports:
- - port: 80
- targetPort: 80
- protocol: TCP
- selector:
- name: nginx
- ---
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: nginx-test
- spec: # 规定了Ingress资源的规格,包括访问规则
- rules: # 定义了访问规则,指定了如何路由到后端服务
- - host: www.aaa.com # 指定了这条规则适用于主机 www.aaa.com
- http: # 定义了 HTTP 访问规则
- paths: # 指定了路径匹配规则
- - path: / # 表示所有以 / 开头的路径都会匹配到这个规则
- pathType: Prefix # 指定了路径匹配类型为前缀匹配
- backend: # 指定了后端服务的配置
- service: # 定义了后端服务的名称和端口号
- name: nginx-svc # 指定了后端服务的名称为 nginx-svc
- port:
- number: 80
-
- [root@master01 nodeport]# kubectl apply -f ingress-nginx.yaml
- [root@master01 nodeport]# kubectl get pod,svc -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- pod/nginx-app-57dd86f5cc-2qgww 1/1 Running 0 2m29s 10.244.1.225 node01
- pod/nginx-app-57dd86f5cc-2rhh5 1/1 Running 0 2m29s 10.244.2.61 node02
-
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
- service/nginx-svc ClusterIP 10.96.206.53
80/TCP 4m26s name=nginx -
- [root@master01 nodeport]# kubectl get ingress
- NAME CLASS HOSTS ADDRESS PORTS AGE
- nginx-test
www.aaa.com 10.96.69.94 80 12m
- [root@master01 nodeport]# kubectl exec -it nginx-app-57dd86f5cc-2qgww sh
- kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
- # echo "this is web1" > /usr/share/nginx/html/index.html
- # exit
- [root@master01 nodeport]# kubectl exec -it nginx-app-57dd86f5cc-2rhh5 sh
- kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
- # echo "this is web2" > /usr/share/nginx/html/index.html
- [root@master01 nodeport]# kubectl get endpoints nginx-svc
- NAME ENDPOINTS AGE
- nginx-svc 10.244.1.225:80,10.244.2.61:80 24m
-
- 任意node地址添加域名解析:
- [root@master01 nodeport]# curl www.aaa.com:32269
- this is web1
- [root@master01 nodeport]# curl www.aaa.com:32269
- this is web2
测试和实践在Kubernetes集群中使用Ingress资源实现同一端口但不同域名的服务路由和负载均衡。具体来说,通过创建两个不同的Service资源,并使用Ingress资源来将不同域名的流量路由到这两个Service上。
① 创建虚拟主机1资源
- [root@master01 nodeport]# mkdir vhost
- [root@master01 nodeport]# cd vhost/
-
- [root@master01 vhost]# vim deployment1.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: deployment1
- spec:
- replicas: 1
- selector:
- matchLabels:
- name: nginx1
- template:
- metadata:
- labels:
- name: nginx1
- spec:
- containers:
- - name: nginx1
- image: soscscs/myapp:v1
- imagePullPolicy: IfNotPresent
- ports:
- - containerPort: 80
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: svc-1
- spec:
- ports:
- - port: 80
- targetPort: 80
- protocol: TCP
- selector:
- name: nginx1
② 启动主机1资源
[root@master01 vhost]# kubectl apply -f deployment1.yaml
③ 创建虚拟主机2资源
- [root@master01 vhost]# vim deployment2.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: deployment2
- spec:
- replicas: 1
- selector:
- matchLabels:
- name: nginx2
- template:
- metadata:
- labels:
- name: nginx2
- spec:
- containers:
- - name: nginx2
- image: soscscs/myapp:v2
- imagePullPolicy: IfNotPresent
- ports:
- - containerPort: 80
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: svc-2
- spec:
- ports:
- - port: 80
- targetPort: 80
- protocol: TCP
- selector:
- name: nginx2
④ 启动主机2资源
- [root@master01 vhost]# kubectl apply -f deployment2.yaml
-
- [root@master01 vhost]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- deployment1-c8d988f6c-hrk88 1/1 Running 0 69s
- deployment2-5588d5cdcd-k6cx6 1/1 Running 0 38s
⑤ 创建ingress资源
- [root@master01 vhost]# vim ingress-nginx.yaml
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: ingress1
- spec: # 规定了 Ingress 资源的规格,包括访问规则
- rules: # 定义了访问规则,指定了如何路由到后端服务
- - host: www.fff.com # 指定了这条规则适用于主机 www.fff.com
- http: # 定义了 HTTP 访问规则
- paths: # 指定了路径匹配规则
- - path: / # 表示所有以 / 开头的路径都会匹配到这个规则
- pathType: Prefix # 指定了路径匹配类型为前缀匹配
- backend: # 指定了后端服务的配置
- service: # 定义了后端服务的名称和端口号
- name: svc-1 # 指定了后端服务的名称为 svc-1
- port:
- number: 80
- ---
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: ingress2
- spec:
- rules:
- - host: www.qqq.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: svc-2
- port:
- number: 80
⑥ 查看svc、ingress信息
- [root@master01 vhost]# kubectl get svc
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- nginx-svc ClusterIP 10.96.206.53
80/TCP 47m - svc-1 ClusterIP 10.96.43.42
80/TCP 5m35s - svc-2 ClusterIP 10.96.30.23
80/TCP 5m4s -
- [root@master01 vhost]# kubectl get svc -n ingress-nginx
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- ingress-nginx NodePort 10.96.69.94
80:32269/TCP,443:32017/TCP 64m -
- [root@master01 vhost]# kubectl get ingress
- NAME CLASS HOSTS ADDRESS PORTS AGE
- ingress1
www.fff.com 10.96.69.94 80 117s - ingress2
www.qqq.com 10.96.69.94 80 117s - nginx-test
www.aaa.com 10.96.69.94 80 49m
⑦ 进入容器编辑页面内容
- [root@master01 vhost]# kubectl get pod
- NAME READY STATUS RESTARTS AGE
- deployment1-c8d988f6c-hrk88 1/1 Running 0 11m
- deployment2-5588d5cdcd-k6cx6 1/1 Running 0 11m
-
- [root@master01 vhost]# kubectl exec -it deployment1-c8d988f6c-hrk88 sh
- kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
- / # echo "this is web01" > /usr/share/nginx/html/index.html
- / # exit
- [root@master01 vhost]# kubectl exec -it deployment2-5588d5cdcd-k6cx6 sh
- kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
- / # echo "this is web02" > /usr/share/nginx/html/index.html
- / # exit
⑧ 测试访问
- [root@master01 vhost]# vim /etc/hosts
- 192.168.190.102 www.aaa.com www.fff.com www.qqq.com
-
- [root@master01 vhost]# curl www.fff.com:32269
- this is web01
- [root@master01 vhost]# curl www.qqq.com:32269
- this is web02
在Kubernetes集群中使用Ingress资源实现通过HTTPS代理访问服务。
生成一个自签名的TLS证书,用于在实验中配置HTTPS代理访问时使用
- [root@master01 vhost]# cd ../
- [root@master01 nodeport]# mkdir https
- [root@master01 nodeport]# cd https/
-
- [root@master01 https]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
- [root@master01 https]# ls
- tls.crt tls.key
-
- # -x509:表示生成自签名的证书。
- # -sha256:表示使用SHA-256算法进行证书签名。
- # -nodes:表示生成的私钥不加密。
- # -days 365:表示证书的有效期为365天。
- # -newkey rsa:2048:表示生成一个2048位的RSA私钥。
- # -keyout tls.key:表示将生成的私钥保存到名为tls.key的文件中。
- # -out tls.crt:表示将生成的证书保存到名为tls.crt的文件中。
- # -subj "/CN=nginxsvc/O=nginxsvc":表示指定证书的主题信息,其中/CN表示Common Name(通用名称),/O表示Organization(组织)。
- [root@master01 https]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
- secret/tls-secret created
- [root@master01 https]# kubectl get secret
- NAME TYPE DATA AGE
- tls-secret kubernetes.io/tls 2 7s
- [root@master01 https]# kubectl describe secret tls-secret
- Name: tls-secret
- Namespace: default
- Labels:
- Annotations:
-
- Type: kubernetes.io/tls
-
- Data
- ====
- tls.crt: 1143 bytes
- tls.key: 1704 bytes
- [root@master01 https]# vim ingress-https.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx-fql
- spec:
- replicas: 1
- selector:
- matchLabels:
- name: nginx
- template:
- metadata:
- labels:
- name: nginx
- spec:
- containers:
- - name: nginx
- image: nginx
- imagePullPolicy: IfNotPresent
- ports:
- - containerPort: 80
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: n-svc-https
- spec:
- ports:
- - port: 80
- targetPort: 80
- protocol: TCP
- selector:
- name: nginx
- ---
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: nginx-https
- spec:
- tls: # 定义了TLS配置,用于配置HTTPS访问
- - hosts:
- - www.lll.com # 指定了使用TLS的主机名为www.lll.com
- secretName: tls-secret # 存储TLS证书和私钥的 Secret 对象的名称为tls-secret
- rules: # 定义了访问规则,指定了如何路由到后端服务
- - host: www.lll.com # 这条规则适用于主机 www.lll.com
- http: # 定义了HTTP访问规则
- paths: # 指定了路径匹配规则
- - path: / # 表示所有以 / 开头的路径都会匹配到这个规则
- pathType: Prefix # 路径匹配类型为前缀匹配
- backend: # 指定了后端服务的配置
- service: # 定义了后端服务的名称和端口号
- name: n-svc-https #后端服务的名称为 n-svc-https
- port:
- number: 80
- [root@master01 https]# kubectl apply -f ingress-https.yaml
-
- [root@master01 https]# kubectl get svc
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- n-svc-https ClusterIP 10.96.7.182
80/TCP 22s -
- [root@master01 https]# kubectl get svc -n ingress-nginx
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- ingress-nginx NodePort 10.96.69.94
80:32269/TCP,443:32017/TCP 101m -
- [root@master01 https]# kubectl get ingress
- NAME CLASS HOSTS ADDRESS PORTS AGE
- nginx-https
www.lll.com 80, 443 5s
在宿主机的 C:\Windows\System32\drivers\etc\hosts 文件中添加 192.168.190.102 www.lll.com 记录。


Basic认证是一种简单的HTTP身份验证方法,通过用户名和密码验证用户身份。
- [root@master01 https]# cd ..
- [root@master01 nodeport]# mkdir basic-auth
- [root@master01 nodeport]# cd basic-auth/
-
- [root@master01 basic-auth]# yum -y install httpd-tools.x86_64
- [root@master01 basic-auth]# htpasswd -c auth fql # 认证文件名必须为 auth
- [root@master01 basic-auth]# htpasswd -c auth fql
- New password: # 密码123
- Re-type new password:
- Adding password for user fql
- [root@master01 basic-auth]# ls
- auth
[root@master01 basic-auth]# kubectl create secret generic basic-auth --from-file=auth
- [root@master01 basic-auth]# vim ingress-auth.yaml
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: ingress-auth
- annotations:
- nginx.ingress.kubernetes.io/auth-type: basic
- nginx.ingress.kubernetes.io/auth-secret: basic-auth
- nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - fql'
- spec:
- rules:
- - host: www.abc.com
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: nginx-svc
- port:
- number: 80
-
- [root@master01 basic-auth]# kubectl apply -f ingress-auth.yaml
-
- [root@master01 basic-auth]# kubectl get ingress
- NAME CLASS HOSTS ADDRESS PORTS AGE
- ingress-auth
www.abc.com 10.96.69.94 80 3m4s


在进行 Nginx Ingress 的 URL 重写实验中,可以配置 Nginx Ingress Controller,然后通过编辑 Ingress 资源规则,使用 Nginx 的 rewrite 指令来修改传入请求的 URL 路径,实现定制的路由和重定向功能。
针对主机 "www.efg.com" 的请求,在经过 Nginx Ingress Controller 处理后,会被重写为指定的目标 URL www.abc.com:32269,并最终路由到名为 "nginx-svc" 的后端服务的端口 80。
① 定义 Ingress
- [root@master01 basic-auth]# vim ingress-rewrite.yaml
- apiVersion: networking.k8s.io/v1
- kind: Ingress
- metadata:
- name: nginx-rewrite
- annotations:
- nginx.ingress.kubernetes.io/rewrite-target: http://www.fff.com:32269
- spec:
- rules:
- - host: www.efg.com #由于www.efg.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: nginx-svc
- port:
- number: 80
② 启动 ingress
- [root@master01 basic-auth]# kubectl apply -f ingress-rewrite.yaml
-
- [root@master01 basic-auth]# kubectl get ingress
- NAME CLASS HOSTS ADDRESS PORTS AGE
- nginx-rewrite
www.efg.com 80 9s
④ 添加宿主机域名解析,访问测试
192.168.190.102 www.lll.com www.abc.com www.efg.com www.fff.com
