Kubernetes Service 详解

schema

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) 提供不同类型的服务,用于不同的应用场景。

  1. ClusterIP

    • 类型:ClusterIP(默认类型)。
    • 应用:用于内部服务。
    • 描述:这种类型将服务公开在群集内部的 IP 地址上,只能从群集内部访问。当我们需要提供内部服务,但不希望从集群外部访问时,可以使用 ClusterIP。例如,您的应用程序需要与数据库服务通信。
  2. NodePort

    • 类型:NodePort。
    • 应用:用于开发和测试。
    • 描述:这种类型将服务公开在每个节点的 IP 地址上的固定端口上,允许从外部访问服务。NodePort 服务通常在开发和测试环境中使用,以便快速从集群外部访问服务。通常不在生产环境中使用,除非有特定的需求。
  3. LoadBalancer

    • 类型:LoadBalancer。
    • 应用:需要从外部访问的生产服务。
    • 描述:这种类型会创建一个外部负载均衡器,通常由云基础设施提供,然后将流量路由到服务。它适用于需要从互联网访问的生产应用程序。例如,提供面向公众的 Web 应用程序。
  4. ExternalName

    • 类型:ExternalName。
    • 应用:映射外部服务。
    • 描述:ExternalName 服务将服务映射到外部 DNS 名称。它用于执行对外部服务的 DNS 查询,这在你想要通过名称访问外部服务而不通过 Kubernetes 服务公开它时很有用。例如,您可以使用它来映射外部数据库服务器。
  5. Headless

    • 类型:无头服务(即没有 ClusterIP 且没有选择器)。
    • 应用:StatefulSet 和直接 Pod 通信。
    • 描述:Headless 服务是一种没有群集内部 IP 或选择器的服务。它不提供负载均衡,而是返回一组 Pod IP,用于直接通信。Headless 服务主要用于 StatefulSet,以确保为各个 Pod 提供稳定的网络标识。它还适用于需要进行直接 Pod 到 Pod 通信的应用。
  6. 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 会被分配给其它健康的节点。它可以在任何以太网网络上运行,不需要特殊的硬件。

nw-metallb-layer2

从上图也不难看出,Layer 2 模式下存在单节点性能瓶颈,服务所有流量都经过一个 Node 节点,这意味着服务的入口带宽被限制为单个节点的带宽。因此,严格意义上来讲,Layer 2 模式的 Service 不是一个真正的 LoadBalancer。

2、BGP 模式

BGP 模式下,集群中所有 Node 都会跟上联路由器建立 BGP 连接,并且会告知路由器应该如何转发 Service 的流量,如下图。

209_OpenShift_BGP_0122

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

image-20231027121158233

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

image-20231027113533936

大概看看,服务是部署在 metallb-system 的名称空间中,如下图。

image-20231027113837151

看看是否正常运行:

kubectl  get svc,pod -n metallb-system

image-20231027121356068

说明: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

image-20231029163442040

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

image-20231029161016783

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/

image-20231029145149923

四、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

image-20231029211515551

此时你就可以通过集群 Service IP 来访问了后端服务了。

curl 10.101.86.52:8080 
# 或
curl -I 10.101.86.52:8080

image-20231029211717028

以上的 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'

image-20231030110811698

此时其他 Pod 就可以通过我们查询的 Service 的 DNS 进行访问测试:

dig @10.96.0.10 externalname-test.default.svc.cluster.local

image-20231030111035548

结果表明:当我们在其他 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。

image-20231030113152021

4、验证

查看每个 Pod 的 DNS 记录,以验证 Headless Service 的 DNS 负载均衡。通过以下方式进入一个Pod:

kubectl exec -it my-statefulset-0 -- /bin/bash

image-20231030113659751

接着我们就可以查看每个 Pod 的 DNS 记录,以验证 Headless Service 的 DNS 负载均衡,如下图,您会看到与 StatefulSet 中每个 Pod 相关的 DNS 记录,其中包括唯一的Pod IP地址。

dig @10.96.0.10 my-headless-service.default.svc.cluster.local

image-20231030113612872

六、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

image-20231030190526324

4、查看资源部署情况

kubectl get all -n ingress-nginx# 如下图ingress-nginx-controller的EXTERNAL-IP是从我们上面的LoadBalancer地址池获取的

image-20231030190944688

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

image-20231030201557413

注意:192.168.56.20 这个 IP 是 ingress-nginx-controller 资源的 EXTERNAL-IP,这也印证了,Ingress 通常会和 LoadBalancer 配合使用。大致示意图如下:

ingress

总结

  • ClusterIP:在集群内部使用,也是默认值;
  • NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节
    点的IP地址和NodePort的端口号访问到集群Pod的服务。NodePort端口范围默认是30000-32767。
  • LoadBalancer:使用云提供商的负载均衡器公开服务;
  • ExternalName:通过返回定义的CNAME别名;
  • Headless:是一种没有群集内部 IP 或选择器的服务。它不提供负载均衡,而是返回一组 Pod IP,用于直接通信。
  • Ingress:Ingress 控制器管理对服务的外部访问,主要用于 HTTP 和 HTTPS 流量。

—END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/124669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【c++|opencv】一、基础操作---1.图像读取

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 有关c操作opencv记录 1. 正文 1.1 图像读取、显示、保存 // 读取、显示、保存图像#include <opencv2/opencv.hpp> #include <iostream>us…

【uniapp】uniapp实现input输入显示数字键盘:

文章目录 一、官网文档&#xff1a;二、文档&#xff1a;三、效果&#xff1a;【1】number&#xff1a;iPhone原生数字键盘不显示小数点【2】digit&#xff1a;【3】digit和inputmode&#xff1a; 一、官网文档&#xff1a; input | uni-app官网 二、文档&#xff1a; 三、效果…

Linux ubuntu安装RStudio

安装RStudio 如果你的实例镜像没有安装Rstudio&#xff0c;可以按照下面的教程进行安装。 关注微信&#xff1a;生信小博士 sudo apt-get install gdebi-core# Ubuntu20.04版本【一般都是这个&#xff0c;具体是哪个&#xff0c;依据你的实例镜像来】 wget https://download…

软考网工历年简答题汇总(2016下半年~2023年上半年)

目录 2016年下半年 2018年上半年 2018年下半年 2021年上半年 2022年上半年 2022年下半年 2023年上半年 2016年下半年 试题一&#xff1a; 【问题 3】若地址规划如图 1-1 所示&#xff0c;从IP 规划方案看该地址的配置可能有哪些方面的考虑&#xff1f; 答案&#xff…

python excel接口自动化测试框架

前言 前些天写了pytestyamlallure接口自动化测试框架这篇文章。 今天采用Excel继续写一个接口自动化测试框架。 设计流程图 这张图是我的excel接口测试框架的一些设计思路。 首先读取excel文件&#xff0c;得到测试信息&#xff0c;然后通过封装的requests方法&#xff0c…

铁合金电炉功率因数补偿装置设计

摘要 由于国内人民生活水平的提高&#xff0c;科技不断地进步&#xff0c;控制不断地完善&#xff0c;从而促使功率因数补偿装置在电力等系统领域占据主导权&#xff0c;也使得功率因数补偿控制系统被广泛应用。在铁合金电炉系统设计领域中&#xff0c;功率因数补偿控制成为目前…

38基于matlab的期货预测,利用PSO优化SVM和未优化的SVM进行对比,得到实际输出和期望输出结果。

基于matlab的期货预测&#xff0c;利用PSO优化SVM和未优化的SVM进行对比&#xff0c;得到实际输出和期望输出结果。线性核函数、多项式、RBF核函数三种核函数任意可选&#xff0c;并给出均方根误差&#xff0c;相对误差等结果&#xff0c;程序已调通&#xff0c;可直接运行。 3…

公网远程访问macOS本地web服务器

# 公网访问macOS本地web服务器【内网穿透】 文章目录 1. 启动Apache服务器2. 公网访问本地web服务2.1 本地安装配置cpolar2.2 创建隧道2.3 测试访问公网地址3. 配置固定二级子域名3.1 保留一个二级子域名3.2 配置二级子域名4. 测试访问公网固定二级子域名 以macOS自带的Apache…

【MySQL系列】- MySQL日志详解

【MySQL系列】- MySQL日志详解 文章目录 【MySQL系列】- MySQL日志详解一、My日志分类二、重做日志&#xff08;redo log&#xff09;redo 日志格式简单日志格式复杂的 redo 日志格式 三、回滚日志&#xff08;undo log&#xff09;undo log的作用undo log数据结构 四、二进制日…

java敏捷开发

敏捷开发&#xff08;Agile Development&#xff09;是一种软件开发方法论&#xff0c;旨在通过灵活、协作和迭代的方式开发高质量的软件。以下是敏捷开发的一些关键特点和原则&#xff1a; 1. **个体和互动重于流程和工具&#xff1a;** 敏捷开发注重人际交互和团队协作&…

【C++进阶】pair容器

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

react中的useState和useImmer的用法

文章目录 一、useState1. 更新基本类型数据2. 更新对象3. 更新嵌套对象4. 更新数组5.更新数组对象 二、Immer1. 什么是Immer2. 使用use-immer更新嵌套对象3. 使用useImmer更新数组内部的对象 一、useState react中文官网教程 1. 更新基本类型数据 在函数式组件中&#xff0c…

Java八大排序——快速排序

1.什么是快速排序 快速排序是一种常用的排序算法&#xff0c;它的基本思想是通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#xff0c;然后再按此方法对这两部分记录分别进行快速排序&#xff0c;以达到整个序列有序的目…

rti skynet Connext observability

RTI公司推出全新Connext Observability Framework&#xff0c;大幅提升智能系统性能_应用_网络_监控 (sohu.com)

正则表达式引擎比较(翻译自:A comparison of regex engines)

原文&#xff1a; A comparison of regex engines – Rust Leipzig 引言 正则表达式&#xff08;或简称regex&#xff09;通常用于模式搜索算法。 有许多不同的正则表达式引擎提供不同的表达式支持、性能约束和语言绑定。 基于 John Maddock 之前的工作 (regex comparison)和…

SQL group by、where和having语句用法

SQL 语句中的 GROUP BY 子句用于将具有相同值的行分组在一起&#xff0c;通常与聚合函数&#xff08;如 COUNT、SUM、AVG 等&#xff09;一起使用。WHERE 子句用于筛选符合条件的行。HAVING 子句则在分组后对分组结果进行进一步筛选。 以下是一个使用 SQL 语句中的 GROUP BY、W…

优化改进YOLOv5算法:加入SPD-Conv模块,让小目标无处遁形——(超详细)

1 SPD-Conv模块 论文:https://arxiv.org/pdf/2208.03641v1.pdf 摘要:卷积神经网络(CNNs)在计算即使觉任务中如图像分类和目标检测等取得了显著的成功。然而,当图像分辨率较低或物体较小时,它们的性能会灾难性下降。这是由于现有CNN常见的设计体系结构中有缺陷,即使用卷积…

UE5实现相机水平矫正

UE5实现相机水平矫正 思路&#xff0c;用HIT获得基于相机视角的 离散采样点&#xff0c;然后根据距离相机距离进行权重分析。 距离越近&#xff0c;采样约中心&#xff0c;即越接近人眼注意点&#xff0c;最后算出加权平均高度&#xff0c;赋予给相机&#xff0c;相机将水平旋…

聚观早报 |2024款飞凡R7官宣;小米14新配色材质

【聚观365】10月27日消息 2024款飞凡R7官宣 小米14新配色材质 金山办公2023第三季度业绩 IBM2023第三季度业绩 新东方2024财年第一季度业绩 2024款飞凡R7官宣 飞凡汽车官宣&#xff0c;2024款飞凡R7将于11月上市&#xff0c;新车将搭载飞凡巴赫座舱&#xff0c;同时超过1…

【Linux】——使用yum进行软件安装和卸载Win和Linux文件交互

个人主页点击直达&#xff1a;小白不是程序媛 Linux系列专栏&#xff1a;Linux被操作记 目录 前言&#xff1a; Linux软件包管理器yum 什么是软件包 ​编辑软件查找 如何安装软件 如何卸载软件 lrzsz的使用 将Windows的文件传送到Linux 将Linux的文件传送到Windows …