Author:rab
目录
- 前言
- 一、ClusterIP
- 1.1 简介
- 1.2 案例
- 二、NodePort
- 2.1 简介
- 2.2 案例
- 三、LoadBalancer
- 3.1 简介
- 3.1.1 MetalLB 简介
- 3.1.2 MetalLB 部署
- 3.1.3 MetalLB 配置
- 3.1.3.1 Layer 2 模式
- 3.1.3.2 BGP 模式
- 3.2 案例
- 3.2.1 部署
- 3.2.2 验证
- 四、ExternalName
- 4.1 简介
- 4.2 案例
- 4.2.1 反代 IP
- 4.2.2 反代域名
- 五、Headless
- 5.1 简介
- 5.2 案例
- 六、Ingress
- 6.1 简介
- 6.2 案例
- 6.2.1 安装 Helm
- 6.2.2 安装 Ingress
- 总结
前言
Kubernetes (K8s) 提供不同类型的服务,用于不同的应用场景。
-
ClusterIP
- 类型:ClusterIP(默认类型)。
- 应用:用于内部服务。
- 描述:这种类型将服务公开在群集内部的 IP 地址上,只能从群集内部访问。当我们需要提供内部服务,但不希望从集群外部访问时,可以使用 ClusterIP。例如,您的应用程序需要与数据库服务通信。
-
NodePort
- 类型:NodePort。
- 应用:用于开发和测试。
- 描述:这种类型将服务公开在每个节点的 IP 地址上的固定端口上,允许从外部访问服务。NodePort 服务通常在开发和测试环境中使用,以便快速从集群外部访问服务。通常不在生产环境中使用,除非有特定的需求。
-
LoadBalancer
- 类型:LoadBalancer。
- 应用:需要从外部访问的生产服务。
- 描述:这种类型会创建一个外部负载均衡器,通常由云基础设施提供,然后将流量路由到服务。它适用于需要从互联网访问的生产应用程序。例如,提供面向公众的 Web 应用程序。
-
ExternalName
- 类型:ExternalName。
- 应用:映射外部服务。
- 描述:ExternalName 服务将服务映射到外部 DNS 名称。它用于执行对外部服务的 DNS 查询,这在你想要通过名称访问外部服务而不通过 Kubernetes 服务公开它时很有用。例如,您可以使用它来映射外部数据库服务器。
-
Headless
- 类型:无头服务(即没有 ClusterIP 且没有选择器)。
- 应用:StatefulSet 和直接 Pod 通信。
- 描述:Headless 服务是一种没有群集内部 IP 或选择器的服务。它不提供负载均衡,而是返回一组 Pod IP,用于直接通信。Headless 服务主要用于 StatefulSet,以确保为各个 Pod 提供稳定的网络标识。它还适用于需要进行直接 Pod 到 Pod 通信的应用。
-
Ingress
这是 Ingress 控制器,不是服务类型,但值得一提。
- 类型:HTTP 和 HTTPS 服务的路由。
- 描述:Ingress 控制器管理对服务的外部访问,主要用于 HTTP 和 HTTPS 流量。它提供基于主机的路由、基于路径的路由、SSL 终止等功能。Ingress 控制器通常与 LoadBalancer 或 NodePort 服务结合使用,将流量路由到集群内特定的服务。
接下来,将逐一对以上 Service 类型进行案例分析。
一、ClusterIP
1.1 简介
在 Kubernetes(K8s)中,ClusterIP
是一种 Service 类型,用于将内部服务映射到集群内的一组Pod。ClusterIP
服务是Kubernetes中最常见的服务类型之一,用于在集群内部提供负载均衡和服务发现。
1.2 案例
1、Deployment 资源
apiVersion: v1
kind: Namespace
metadata:name: myweblabels:name: ops
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxnamespace: myweblabels:app: webdemo
spec:replicas: 3selector:matchLabels:app: demotemplate:metadata:labels:app: demospec:containers:- name: nginximage: nginx:1.21.4ports:- containerPort: 80
2、Service 资源
apiVersion: v1 # service版本
kind: Service # 对象类型(如service、deployment、pod等)
metadata: # 元数据信息(名称、名称空间等)name: nginx-srv # 指定service的名称(自定义)namespace: myweb # 指定service的名称空间(与deployment资源的名称空间必须保持一致)
spec: # service的规格selector: # service选择器(逻辑上代表一组Pod)app: demo # 选择标签为app:demo的一组后端Pod(这里的标签必须与上面deployment资源中选择器selector一致)ports: # service端口- protocol: TCP # 通信协议(支持TCP/UDP/SCTP,默认是TCP)port: 80 # service的端口(注意不是nginx的端口,这里可自定义)targetPort: 80 # 后端Pod的端口(即是我们上面Deployment的Pod端口 => containerPort)type: ClusterIP # 指定service的类型(不指定默认为ClusterIP)
此时只能从群集内部访问,可通过集群 Service IP、Pod IP 来访问资源。注意的是,当我们没指定 type 时,默认就是 ClusterIP 类型。
二、NodePort
2.1 简介
Kubernetes中的NodePort
是一种Service类型,用于将外部流量引导到Kubernetes集群内的一组Pod。NodePort
服务允许您通过一个静态端口(在每个节点上都开放)将外部流量引导到内部服务,并且通常用于需要从外部网络访问应用程序的情况。
2.2 案例
1、Deployment 资源
apiVersion: v1
kind: Namespace
metadata:name: myweblabels:name: ops
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxnamespace: myweblabels:app: webdemo
spec:replicas: 3selector:matchLabels:app: demotemplate:metadata:labels:app: demospec:containers:- name: nginximage: nginx:1.21.4ports:- containerPort: 80
2、Service 资源
apiVersion: v1
kind: Service
metadata:name: nginx-srvnamespace: myweb
spec:selector:app: demoports:- protocol: TCPport: 80targetPort: 80nodePort: 30333 # service端口映射到主机节点的端口(即将service的80端口映射到主机节点的30333端口)type: NodePort # 此时需指定service类型为NodePort
与 NodePort 类似,不同的就是指定 type 为 NodePort,此时集群外部就可以通过访问我们 Host 节点 IP 来访问我们集群资源了(可通过集群 节点 IP、Service IP、Pod IP 来访问资源)。你会注意到,service 资源中多了 nodePort 字段,该字段用于主机节点端口映射,也就是说我们会将 service 的 80 端口映射到集群节点的 30333 端口,便于集群外部可通过集群节点的 30333 端口来访问我们的集群资源。
三、LoadBalancer
3.1 简介
Kubernetes 中的 LoadBalancer 服务是一种 Service 类型,用于将外部流量负载均衡到Kubernetes集群内的多个Pod。LoadBalancer服务允许您在不了解集群内部结构的情况下暴露应用程序,并且由云提供商(如 AWS、GCP、Azure)或 MetalLB 等工具来处理负载均衡的配置和管理。
ClustrerIP、NodePort
这两种无论在内网还是公网环境下使用都很常见,只有 LoadBalancer
大部分情况下只适用于支持外部负载均衡器的云提供商(AWS、阿里云、华为云等)使用。
如果我们使用 AWS、阿里云、华为云等公有云,那么一般来说我们给 Service 的 Type 写成 LoadBalancer,云服务厂商就会分配一个 External IP 给我们的 Service,我们只需要访问这个 External IP,其内部就能自动均衡我们的流量到各个实例上。
那我们自建的 Metallb 要如何配置呢?首先它是一款开源的 K8s 负载均衡控制器,只要部署该控制器,我们的 Service 就可以拿到 IP 了(从我们配置的 Metallb 的地址池中获取),实际上就是这个 IP 就是我们 K8s 集群中主机节点上 iptables 里的一条记录。
3.1.1 MetalLB 简介
一旦 MetalLB 为服务分配了IP地址,它需要对外宣告此 IP 地址,并让外部主机可以路由到此 IP,外部声明有两种模式。
1、Layer 2 模式
Layer 2 模式下,每个 Service 会有集群中的一个 Node 来负责。服务的入口流量全部经由单个节点,然后该节点的 Kube-Proxy 会把流量再转发给服务的 Pods。也就是说,该模式下 MetalLB 并没有真正提供负载均衡器。尽管如此,MetalLB 提供了故障转移功能,如果持有 IP 的节点出现故障,则默认 10 秒后即发生故障转移,IP 会被分配给其它健康的节点。它可以在任何以太网网络上运行,不需要特殊的硬件。
从上图也不难看出,Layer 2 模式下存在单节点性能瓶颈,服务所有流量都经过一个 Node 节点,这意味着服务的入口带宽被限制为单个节点的带宽。因此,严格意义上来讲,Layer 2 模式的 Service 不是一个真正的 LoadBalancer。
2、BGP 模式
BGP 模式下,集群中所有 Node 都会跟上联路由器建立 BGP 连接,并且会告知路由器应该如何转发 Service 的流量,如下图。
BGP 模式下才是一个真正的 LoadBalancer,通过 BGP 协议正确分布流量,不再需要一个 Leader 节点。
但该模式下要注意:需要上层路由器支持 BGP。而且因为 BGP 单 Session 的限制,如果 Calico 也是使用的 BGP 模式,就会有冲突从而导致 Metallb 无法正常工作。
3.1.2 MetalLB 部署
官网:https://metallb.universe.tf/installation/
参考1:https://access.redhat.com/documentation/
参考2:https://www.cnblogs.com/gaoyukun/articles/17156408.html
参考3:https://www.infvie.com/ops-notes/kubernetes-load-balancer-metallb.html
参考4:https://blog.csdn.net/zuoyang1990/article/details/128898396
1、K8s 启用 ARP 模式
如果环境是 Kubernetes v1.14.2+ 使用 IPVS模式,必须启用 ARP 模式。
kubectl edit configmap -n kube-system kube-proxy
2、部署 MetalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml# 如果在线无法部署,可将yml文件下载到本地后再上传服务器执行(如下图)
kubectl apply -f metallb-native.yaml
大概看看,服务是部署在 metallb-system 的名称空间中,如下图。
看看是否正常运行:
kubectl get svc,pod -n metallb-system
说明:controller 负责 IP 地址的分配,以及 service 和 endpoint 的监听,speaker 负责保证 service 地址可达,例如 Layer 2 模式下,speaker 会负责ARP请求应答。部署完成后,还需配置 IP 地址池。
3.1.3 MetalLB 配置
3.1.3.1 Layer 2 模式
1、给 Metallb 创建 IP 地址池
vim iptool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: defaultnamespace: metallb-system
spec:addresses:- 192.168.56.20-192.168.56.110autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: defaultnamespace: metallb-system
spec:ipAddressPools:- default
上面例子,IP 地址池为 192.168.56.20 - 192.168.56.110。
注意:IP段根据自己实际情况来设置(我的虚拟机测试环境网段是 192.168.56.0/24)
2、应用配置文件
kubectl apply -f iptool.yaml
3、查看状态
kubectl get IPAddressPool,L2Advertisement -n metallb-system
3.1.3.2 BGP 模式
这部分要结合你本地的路由来具体配置(且本地路由必须支持 BGP 模式),这里我就不演示了。具体步骤可参考这部分内容 => 配置 MetalLB BGP peer。
3.2 案例
3.2.1 部署
1、创建 yml 测试文件
注:这些资源的 namespace 不必与 metallb 的 namespace 保持一致(默认或指定为你自定义的 namespace 即可)。
vim demo.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginxlabels:app: webdemo
spec:replicas: 2selector:matchLabels:app: demotemplate:metadata:labels:app: demospec:containers:- name: nginximage: nginx:1.21.4ports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-srv
spec:selector:app: demoports:- protocol: TCPport: 80targetPort: 80nodePort: 30333type: LoadBalancer
2、应用配置
kubectl apply -f demo.yml
3、验证是否获取地址池 IP
kubectl get service# 如下图,正好分配到了我们指定IP地址池内的IP
3.2.2 验证
本地浏览器访问!注意,访问地址格式为
http://<EXTERNAL-IP>:<ServicePort>
,其中EXTERNAL-IP
就是分配给我们的 IP 地址,ServicePort
是 80,而不是 30333。因此你可以两种方式访问:
- 通过分配的 IP 地址:http://192.168.56.20/
- 通过K8s集群节点IP地址:http://192.168.56.160:30333/、http://192.168.56.161:30333/、http://192.168.56.162:30333/
四、ExternalName
4.1 简介
Kubernetes 中的 ExternalName
服务是一种特殊类型的服务,它允许将一个 Kubernetes 服务映射到一个外部域名(或外部服务)。这对于将内部Kubernetes集群内的服务与外部服务(例如外部数据库、第三方API等)关联起来非常有用。
ExternalName
服务通常用于以下情况:
- 访问外部数据库。
- 访问外部第三方 API。
- 切换外部服务提供商的域名。
- 隐藏外部服务的实际域名,以提供更友好的服务名。
总之,ExternalName
服务是 Kubernetes 中一种非常有用的服务类型,它允许将内部服务名映射到外部域名,提供了灵活性和透明性,以便访问外部服务。这对于将内部应用程序与外部服务集成起到了重要作用。
4.2 案例
4.2.1 反代 IP
1、创建 yml 测试文件
vim ep.yml
---
apiVersion: v1
kind: Endpoints
metadata:name: baidu-ep # 与svc资源的metadata.name保持一致
subsets:
- addresses:- ip: 220.181.38.148ports:- name: baidu # 与svc资源的spec.ports.name保持一致port: 80protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: baidu-svc # 与ep资源的metadata.name保持一致
spec:ports:- name: baidu # 与ep资源的subsets.ports.name保持一致port: 8080protocol: TCPtargetPort: 80 # 这里的targetPort是ep资源中的port
kubectl apply -f ep.yml
2、验证
kubectl get svc,ep
此时你就可以通过集群 Service IP 来访问了后端服务了。
curl 10.101.86.52:8080
# 或
curl -I 10.101.86.52:8080
以上的 Service 类型是 ClusterIP,如果你想通过 K8s 集群外部来访问,修改 Service 类型为 NodePort 即可,这里不再演示。
4.2.2 反代域名
1、创建 yml 测试文件
vim externalName.yaml
apiVersion: v1
kind: Service
metadata:labels:app: externalname-testname: externalname-test
spec:ports:- name: httpport: 80protocol: tcptargetPort: 80sessionAffinity: Nonetype: ExternalNameexternalName: www.baidu.com
kubectl apply -f externalName.yaml
2、验证
创建一个测试 Pod:
vim test-pod.yml
apiVersion: v1
kind: Pod
metadata:name: my-pod
spec:containers:- name: my-containerimage: nginx
kubectl apply -f test-pod.yml
启动后可先进入测试 Pod 中查看一下 /etc/resolve.conf
在看看 Service 的 DNS:
kubectl get svc externalname-test -n default -o jsonpath='{.metadata.name}.{.metadata.namespace}.svc.cluster.local'
此时其他 Pod 就可以通过我们查询的 Service 的 DNS 进行访问测试:
dig @10.96.0.10 externalname-test.default.svc.cluster.local
结果表明:当我们在其他 Pod 访问 ExternalName 类型的 Service 时,实现了反代的效果。
五、Headless
5.1 简介
Kubernetes 中的 Headless Service 是一种特殊类型的 Service,与标准的 ClusterIP Service 不同,它不会分配 ClusterIP,而是用于实现服务的 DNS 负载均衡。Headless Service 通常用于需要直接与 Pod 的 IP 地址交互或实现服务发现的情况,特别适用于需要直接访问 Pod IP 地址或实现服务发现的情况。它提供了更高级别的控制,同时还允许使用 Kubernetes 的内置 DNS 解析来管理服务和 Pod 之间的通信。
5.2 案例
1、创建一个 Headless Service 的 YAML 文件
vim headless-service.yaml
apiVersion: v1
kind: Service
metadata:name: my-headless-service
spec:clusterIP: Noneselector:app: my-appports:- protocol: TCPport: 80
在上述 YAML 文件中,我们定义了一个名为 my-headless-service
的 Headless Service,clusterIP
设置为 None
,这将创建一个 Headless Service。Service 选择了带有标签 app: my-app
的 Pod。
2、创建一个 StatefulSet 用于部署有状态的Pod
vim statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: my-statefulset
spec:serviceName: my-headless-servicereplicas: 3selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: my-containerimage: nginx
在上述 YAML 文件中,我们创建了一个 StatefulSet,它使用 my-headless-service
作为服务名称,创建了 3 个具有 app: my-app
标签的 Pod,这些 Pod 将具有唯一的标识。
3、使用kubectl
部署 Headless Service 和 StatefulSet
kubectl apply -f headless-service.yaml
kubectl apply -f statefulset.yaml
这将创建 Headless Service 以及 StatefulSet 中的 Pod。
4、验证
查看每个 Pod 的 DNS 记录,以验证 Headless Service 的 DNS 负载均衡。通过以下方式进入一个Pod:
kubectl exec -it my-statefulset-0 -- /bin/bash
接着我们就可以查看每个 Pod 的 DNS 记录,以验证 Headless Service 的 DNS 负载均衡,如下图,您会看到与 StatefulSet 中每个 Pod 相关的 DNS 记录,其中包括唯一的Pod IP地址。
dig @10.96.0.10 my-headless-service.default.svc.cluster.local
六、Ingress
6.1 简介
Kubernetes Ingress 是一种资源对象,用于管理外部 HTTP 和 HTTPS 访问到 Kubernetes 集群内部的服务。它充当 HTTP 和 HTTPS 流量的入口点,允许我们定义请求路由、负载均衡、SSL 终止等功能。
通俗来讲,Ingress 和 Service、Deployment 类似,也是一个 k8s 的资源类型,Ingress 用于实现用域名的方式访问 k8s 内部应用管理对集群中的服务(通常是 HTTP 或 HTTPS)的外部访问的 API 对象。
官方文档:https://kubernetes.github.io/ingress-nginx/deploy/
6.2 案例
6.2.1 安装 Helm
具体安装看《K8s 之 Helm 部署 MySQL 5.7》。
6.2.2 安装 Ingress
可通过两种方式安装:Yaml、Helm(本质上就是 Yaml 文件)
1、通过 Helm 方式部署
# 添加helm仓库
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx# 下载 Ingress 的 Helm 包至本地
mkdir /opt/helm_images && cd /opt/helm_images
helm pull ingress-nginx/ingress-nginx
2、通过 Yaml 文件部署
本次我们通过该方式部署。
参考:https://zhuanlan.zhihu.com/p/590474850
vim ingressdeploy.yaml
apiVersion: v1
kind: Namespace
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxname: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginxnamespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginxnamespace: ingress-nginx
rules:
- apiGroups:- ""resources:- namespacesverbs:- get
- apiGroups:- ""resources:- configmaps- pods- secrets- endpointsverbs:- get- list- watch
- apiGroups:- ""resources:- servicesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingressesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingresses/statusverbs:- update
- apiGroups:- networking.k8s.ioresources:- ingressclassesverbs:- get- list- watch
- apiGroups:- ""resourceNames:- ingress-controller-leaderresources:- configmapsverbs:- get- update
- apiGroups:- ""resources:- configmapsverbs:- create
- apiGroups:- coordination.k8s.ioresourceNames:- ingress-controller-leaderresources:- leasesverbs:- get- update
- apiGroups:- coordination.k8s.ioresources:- leasesverbs:- create
- apiGroups:- ""resources:- eventsverbs:- create- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admissionnamespace: ingress-nginx
rules:
- apiGroups:- ""resources:- secretsverbs:- get- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx
rules:
- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secrets- namespacesverbs:- list- watch
- apiGroups:- coordination.k8s.ioresources:- leasesverbs:- list- watch
- apiGroups:- ""resources:- nodesverbs:- get
- apiGroups:- ""resources:- servicesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingressesverbs:- get- list- watch
- apiGroups:- ""resources:- eventsverbs:- create- patch
- apiGroups:- networking.k8s.ioresources:- ingresses/statusverbs:- update
- apiGroups:- networking.k8s.ioresources:- ingressclassesverbs:- get- list- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission
rules:
- apiGroups:- admissionregistration.k8s.ioresources:- validatingwebhookconfigurationsverbs:- get- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginxnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx
subjects:
- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admissionnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx-admission
subjects:
- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx
subjects:
- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx-admission
subjects:
- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: v1
data:allow-snippet-annotations: "true"
kind: ConfigMap
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-controllernamespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-controllernamespace: ingress-nginx
spec:externalTrafficPolicy: LocalipFamilies:- IPv4ipFamilyPolicy: SingleStackports:- appProtocol: httpname: httpport: 80protocol: TCPtargetPort: http- appProtocol: httpsname: httpsport: 443protocol: TCPtargetPort: httpsselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-controller-admissionnamespace: ingress-nginx
spec:ports:- appProtocol: httpsname: https-webhookport: 443targetPort: webhookselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-controllernamespace: ingress-nginx
spec:minReadySeconds: 0revisionHistoryLimit: 10selector:matchLabels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxspec:containers:- args:- /nginx-ingress-controller- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller- --election-id=ingress-controller-leader- --controller-class=k8s.io/ingress-nginx- --ingress-class=nginx- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller- --validating-webhook=:8443- --validating-webhook-certificate=/usr/local/certificates/cert- --validating-webhook-key=/usr/local/certificates/keyenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: LD_PRELOADvalue: /usr/local/lib/libmimalloc.soimage: dyrnq/ingress-nginx-controller:v1.3.0imagePullPolicy: IfNotPresentlifecycle:preStop:exec:command:- /wait-shutdownlivenessProbe:failureThreshold: 5httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1name: controllerports:- containerPort: 80name: httpprotocol: TCP- containerPort: 443name: httpsprotocol: TCP- containerPort: 8443name: webhookprotocol: TCPreadinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1resources:requests:cpu: 100mmemory: 90MisecurityContext:allowPrivilegeEscalation: truecapabilities:add:- NET_BIND_SERVICEdrop:- ALLrunAsUser: 101volumeMounts:- mountPath: /usr/local/certificates/name: webhook-certreadOnly: truednsPolicy: ClusterFirstnodeSelector:kubernetes.io/os: linuxserviceAccountName: ingress-nginxterminationGracePeriodSeconds: 300volumes:- name: webhook-certsecret:secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission-createnamespace: ingress-nginx
spec:template:metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission-createspec:containers:- args:- create- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc- --namespace=$(POD_NAMESPACE)- --secret-name=ingress-nginx-admissionenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceimage: dyrnq/kube-webhook-certgen:v1.1.1imagePullPolicy: IfNotPresentname: createsecurityContext:allowPrivilegeEscalation: falsenodeSelector:kubernetes.io/os: linuxrestartPolicy: OnFailuresecurityContext:fsGroup: 2000runAsNonRoot: truerunAsUser: 2000serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission-patchnamespace: ingress-nginx
spec:template:metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission-patchspec:containers:- args:- patch- --webhook-name=ingress-nginx-admission- --namespace=$(POD_NAMESPACE)- --patch-mutating=false- --secret-name=ingress-nginx-admission- --patch-failure-policy=Failenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceimage: dyrnq/kube-webhook-certgen:v1.1.1imagePullPolicy: IfNotPresentname: patchsecurityContext:allowPrivilegeEscalation: falsenodeSelector:kubernetes.io/os: linuxrestartPolicy: OnFailuresecurityContext:fsGroup: 2000runAsNonRoot: truerunAsUser: 2000serviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: nginx
spec:controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.3.0name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:- v1clientConfig:service:name: ingress-nginx-controller-admissionnamespace: ingress-nginxpath: /networking/v1/ingressesfailurePolicy: FailmatchPolicy: Equivalentname: validate.nginx.ingress.kubernetes.io rules:- apiGroups:- networking.k8s.ioapiVersions:- v1operations:- CREATE- UPDATEresources:- ingressessideEffects: None
3、执行部署
kubectl apply -f ingressdeploy.yaml
4、查看资源部署情况
kubectl get all -n ingress-nginx# 如下图ingress-nginx-controller的EXTERNAL-IP是从我们上面的LoadBalancer地址池获取的
5、验证
创建一个 Ingress
vim ingress-1.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-mytestnamespace: default #必须与service的名称空间一致annotations:kubernetes.io/ingress.class: "nginx"
spec:rules:- host: "mytest.zrsops.com"http:paths:- path: "/"pathType: Exactbackend:service: name: mytest #service名称 port: number: 80 #service端口
创建一个 Nginx 资源
vim ingress-ng.yml
apiVersion: apps/v1
kind: Deployment
metadata:name: mytestnamespace: default
spec:replicas: 1selector:matchLabels:app: mytestrelease: v1env: testtemplate:metadata:labels:app: mytestrelease: v1env: testspec:containers:- name: mytestimage: nginx imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: mytestnamespace: default
spec:type: ClusterIP #默认类型selector:app: mytestrelease: v1env: testports:- name: httpport: 80targetPort: 80
执行创建
kubectl apply -f ingress-1.yml
kubectl apply -f ingress-ng.yml
在浏览器本地验证
先在 Windows Hosts 文件添加如下内容。
路径:C:\Windows\System32\drivers\etc\hosts
192.168.56.20 mytest.zrsops.com
注意:192.168.56.20 这个 IP 是 ingress-nginx-controller 资源的 EXTERNAL-IP,这也印证了,Ingress 通常会和 LoadBalancer 配合使用。大致示意图如下:
总结
- ClusterIP:在集群内部使用,也是默认值;
- NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节
点的IP地址和NodePort的端口号访问到集群Pod的服务。NodePort端口范围默认是30000-32767。 - LoadBalancer:使用云提供商的负载均衡器公开服务;
- ExternalName:通过返回定义的CNAME别名;
- Headless:是一种没有群集内部 IP 或选择器的服务。它不提供负载均衡,而是返回一组 Pod IP,用于直接通信。
- Ingress:Ingress 控制器管理对服务的外部访问,主要用于 HTTP 和 HTTPS 流量。
—END