草庐IT

k8s指南-Service

还是转转 2024-04-05 原文

目录:
(1)k8s指南-概述
(2)k8s指南-架构
(3)k8s指南-工作负载(1)
(4)k8s指南-工作负载(2)
(5)k8s指南-工作负载(3)
(6)k8s指南-工作负载(4)
(7)k8s指南-Service
(8)k8s指南-Ingress
(9)k8s指南-DNS与服务发现
(10)K8S指南-平滑升级与自动扩缩容


在k8s集群中,虽然每个pod都会被分配一个单独的ip地址,但由于pod是有生命周期的,一旦pod被销毁,其对应的ip地址就会消失。如果在某地方需要用到这个ip,那就会出问题。Service就是用来解决这个问题的。

在k8s中,Service是一种抽象概念,它定义了一组逻辑pod和访问这些pod的策略。Service所拥有的pod集合通常是由选择器来定义的。

实际上,k8s中的service概念和我们通常提到的微服务中的服务是一样的。只不过k8s中的service是一种具体资源。

每个Service都有一个集群ip,表示服务对外的ip地址,所有访问该服务的网络请求直接访问这个ip地址,然后由service将其转发到服务对应的实际pods中的某一个。

Service与DNS一起实现K8S中的服务发现,Service与Ingress一起实现K8S中的负载均衡,这也是Service的两个主要作用

定义服务

Kubernetes中的Service是一个REST对象,类似于pod。像所有的REST对象一样,可以通过POST方法将服务定义发过API服务器来创建新的实例。
下面是一个示例:

apiVersiono: v1
kind: Service
metadata:
    name : my-service
spec:
     selector:
	   app.kubernetes.io/name: MyApp
     ports:
	   - protocol: TCP
	   port: 80
	   targetPort: 9376

以上文件会创建一个服务叫my-service,该服务可以将请求转发到服务对应的某个pod的9376端口。

Pod中的端口定义是有名字的,你可以在service的targetPort属性中引用这些名称。如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: proxy
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: http-web-svc

服务的默认协议是TCP,你还可以使用任何其他受支持的协议,如UDP或者SCTP等。

Kubernetes在服务对象上也支持多个端口定义,每个端口定义可以具有相同的protocol,也可以具有不同的protocol。

没有选择符的Service

由于选择符的存在,服务最常见的用法是为k8s pod的访问提供抽象,但是当与相应的EndpointSlices对象一起使用且没有选择算符时,服务也可以为其他类型的后端提供抽象,包括在集群外运行的后端。例如:

  • 希望在生产环境中使用外部的数据库集群,但在测试环境使用自己的数据库。
  • 希望服务指向另一个命名空间或其他集群中的服务。

在这些场景中,你可以定义没有选择符的Service,如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于此服务没有选择符,因此不会自动创建相应的EndpointSlice对象。你可以通过手动添加EndpointSlice对象,将服务手动映射到运行该服务的网络地址和端口上:

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: my-service-1 # 按惯例将服务的名称用作 EndpointSlice 名称的前缀
  labels:
    # 你应设置 "kubernetes.io/service-name" 标签。
    # 设置其值以匹配服务的名称
    kubernetes.io/service-name: my-service
addressType: IPv4
ports:
  - name: '' # 留空,因为 port 9376 未被 IANA 分配为已注册端口
    appProtocol: http
    protocol: TCP
    port: 9376
endpoints:
  - addresses:
      - "10.4.5.6" # 此列表中的 IP 地址可以按任何顺序显示
      - "10.1.2.3"

多端口service

对于某些服务,你需要公开多个端口。Kubernetes允许你在Service对象上配置多个端口定义。为服务使用多个端口时,必须提供所有端口名称,以便它们无歧义。如:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
    - name: https
      protocol: TCP
      port: 443
      targetPort: 9377

与一般的Kubernetes名称一样,端口名称只能包含小写字母,数字,字符和 -。端口名称必须以字母数字字符开头和结尾。

选择自己的ip地址

在Service创建的请求中,可以通过设置spec.clusterIP字段来指定自己的集群IP地址的,比如,希望替换一个已经存在的DNS条目,或者遗留系统已经配置了一个固定的IP且很难重新配置。

用户选择的ip地址必须合法,并且这个IP地址在service-cluster-ip-range CIDR范围内,如果ip地址不合法,API服务器会返回422错误码。

服务发现

Kubernetes支持两种基本的服务发现模式 – 环境变量和DNS。

环境变量

当Pod运行在node上时,kubelet会为每个活跃的Pod添加一组环境变量: {SVCNAME}_SERVICE_HOST{SVCNAME}_SERVICE_PORT。注意这里的Service的名称需大写,横线被转成下划线。

启动前文的nginx-deployment,然后进入其中一个pod,查看环境变量,可以看到如下结果:

root@nginx-deployment-7fb96c846b-66rwr:/# env | grep SERVICE     
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.96.0.1

系统把当前default空间中的kubernetes本身的服务host和port都添加到当前pod中了。

如果先创建客户端pod,再创建服务端service,此时客户端pod不会设定service的host和port到客户端pod中去。换句话说,想通过环境变量的方式去做服务发现,则必须先创建service,再生成客户端pod。而使用DNS查到服务的集群IP,则不用考虑此问题。

DNS
你可以使用附加组件为Kubernetes集群设置DNS服务。DNS服务器(如CoreDNS)监视Kubernetes API中的新服务,并为每个服务创建一组DNS记录。
如果在整个集群中都启用DNS,则所有pod都应该能够通过其DNS名称自动解析服务。

Headless Services

有时不需要负载均衡和单独的Service IP,在这种情况下,可以通过指定Cluster IP的值为"None"来创建Headless Service。

对于无头Services并不会分配Cluster IP,kube-proxy 不会处理它们,并且平台也不会为它们进行负载均衡和路由。DNS如何实现自动配置,依赖于Service是否定义了选择算符。

带选择符的服务
对定义了选择算符的无头服务,Kubernetes控制平面在Kuberntes API中创建EndpointSlice对象,并且修改DNS配置返回A或者AAAA记录(IPv4或IPv6地址),通过此地址直接到达Service对应的后端pod上。

无选择符的服务
对没有选择符的无头服务,控制平面不会创建EndpointSlice对象,然而DNS系统会查找和配置以下之一:

  • 对于type: ExternalName服务,查找和配置其CNAME记录。
  • 对于其他类型的服务,针对Service的就绪端点的所有IP地址,查找和配置DNS A/AAAA记录:对于IPv4端点,DNS系统创建A条记录;对于IPv6端点,创建AAAA条记录。

发布服务

对一些应用的某些部分,可能希望将其暴露给kubernetes集群外部的ip地址。Kubernetes的serviceTypes允许你指定所需要的Service类型。
Type的取值以及行为如下:

  • ClusterIP:通过集群内部IP暴露服务,选择该值时服务只能够在集群内部访问。这也是type的默认值。
  • NodePort:通过每个节点上的IP和静态端口(NodePort)暴露服务。为了让节点端口可用,Kubernetes设置了集群IP地址,这等同于你请求type:ClusterIP的服务。
  • LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。外部负载均衡器可以将流量路由到自动创建的NodePort服务和ClusterIP服务上。
  • ExternalName:通过返回CNAME记录和对应值,可以将服务映射到externalName字段的内容(如foo.bar.example.com)。无需创建任何类型代理。

NodePort类型

如果你将type字段设置为NodePort,则kubernetes控制平面将在--service-node-port-range标志指定的范围内分配端口(默认值:30000-32767)。每个节点将那个端口代理到你的服务中,你的服务在其.spec.ports[*].nodePort字段中报告已分配的端口。

使用NodePort可以让你自由设置自己的负载均衡解决方案,配置Kubernetes不完全支持的环境,甚至直接暴露一个或多个节点的IP地址。

对于NodePort服务,Kubernetes会额外分配一个端口(TCP、UDP或SCTP以匹配服务的协议)。集群中每个节点都将自动监听分配的端口并将流量转发到与该服务关联的某个就绪端点。通过使用适当的协议和适当的端口连接到所有节点,你将能够从集群外部使用NodePort类型的服务。

以下是一个NodePort类型的服务,它指定了一个NodePort值30007。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: MyApp
  ports:
      # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80
      targetPort: 80
      # 可选字段
      # 默认情况下,为了方便起见,Kubernetes 控制平面会从某个范围内分配一个端口号(默认:30000-32767)
      nodePort: 30007

LoadBalancer类型

在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 “LoadBalancer”, 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。示例如下:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.0.2.127

来自外部负载均衡器的流量将直接重定向到后端 Pod 上,不过实际它们是如何工作的,这要依赖于云提供商。

某些云提供商允许设置 loadBalancerIP。 在这些情况下,将根据用户设置的 loadBalancerIP 来创建负载均衡器。 如果没有设置 loadBalancerIP 字段,将会给负载均衡器指派一个临时 IP。 如果设置了 loadBalancerIP,但云提供商并不支持这种特性,那么设置的 loadBalancerIP 值将会被忽略掉。

要实现 type: LoadBalancer 的服务,Kubernetes 通常首先进行与请求 type: NodePort 服务等效的更改。 cloud-controller-manager 组件然后配置外部负载均衡器以将流量转发到已分配的节点端口。

作为 Alpha 特性,你可以将负载均衡服务配置为忽略分配节点端口, 前提是云提供商实现支持这点。

参考资料

[1]. https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/#type-nodeport

有关k8s指南-Service的更多相关文章

  1. ruby-on-rails - 将 Amazon Simple Notification service SNS 与 ruby​​ 结合使用 - 2

    很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visitthehelpcenter.关闭9年前。我需要从基于ruby​​的应用程序使用AmazonSimpleNotificationService,但不知道从哪里开始。您对从哪里开始有什么建议吗?

  2. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

  3. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  4. ruby - Ruby gems 的问题(损坏?)试图让指南针在 npm 中工作 - 2

    我不是Ruby专家,但想弄清楚发生了什么,因为我试图让指南针在节点应用程序中工作,但我的Ruby似乎坏了。打字:ruby--version让我:ruby2.1.1p76(2014-02-24revision45161)[x86_64-darwin13.0]我安装了Homebrew,之前遇到过Ruby版本的问题,但它似乎已安装并且可以正常工作。但是,当我使用gem输入请求时,出现此错误:$gem-hErrorloadingRubyGemsplugin"/Users/user_dir/.rvm/gems/ruby-2.1.1@global/gems/executable-hooks-1.3

  5. ruby-on-rails - Rails 'service objects' 最佳实践 - 类方法或实例化 - 2

    我正在按照我一直在研究的研讨会实现“服务对象”,我正在构建一个redditAPI应用程序。我需要对象返回一些东西,所以我不能只执行初始化程序中的所有内容。我有这两个选择:选项1:类需要实例化classSubListFromUserdefuser_subscribed_subs(client)@client=client@subreddits=sort_subs_by_name(user_subs_from_reddit)endprivatedefsort_subs_by_name(subreddits)subreddits.sort_by{|sr|sr[:name].downcase}

  6. ruby-on-rails - Elasticsearch 问题 : Cannot connect AWS elasticsearch service - 2

    我有一个关于配置elasticsearch以连接AWSelasticsearch服务以在生产环境中运行项目的问题。我的gem文件:gem'searchkick'gem'faraday_middleware-aws-signers-v4'gem'aws-sdk','~>2'gem"elasticsearch",">=1.0.15"引用:https://github.com/ankane/searchkick我的config/initializers/elasticsearch.rb文件:require"faraday_middleware/aws_signers_v4"ENV["ELAS

  7. ruby - 使用指南针安装 bootstrap sass - 2

    我正在尝试安装bootstrap-sass并收到以下错误。我试过旧版本的sass,但bundler一直在安装3.3.0。WARN:UnresolvedspecsduringGem::Specification.reset:sass(~>3.2)WARN:Clearingoutunresolvedspecs.Pleasereportabugifthiscausesproblems./Library/Ruby/Gems/2.0.0/gems/compass-0.12.2/lib/compass/sass_extensions/monkey_patches/browser_support.r

  8. JMockit 使用指南 - 2

    目录配置模拟模拟类型与实例期望录制-回放-验证指定调用计数验证指定自定义结果验证调用参数联级模拟部分模拟模拟未实现的类其他伪装伪装方法及类伪装未实现类本文主要内容如何在SpringBoot中配置使用JMockit如何mock/faking依赖的对象如何对行为mock如何VerificationJMockit之所以强大,是因其使用了javaagent对类的字节码做了修改,在JVM的所有mock工具中,它是功能最强大的。同时注解又是最少的。配置在SpringBoot项目中使用JMockit隔离代码做单元测试,需要做以下配置引入JMockit依赖。dependencies>dependency>gr

  9. k8s-污点 (Taint)和容忍 (Tolerations) - 2

    文章目录一、污点(Taint)1、污点简介2、污点的组成3、污点的设置和去除二、容忍(Tolerations)1、容忍简介2、容忍的基本用法3、示例4、多污点与多容忍配置三、警戒(cordon)和转移(drain)四、Pod启动阶段(相位phase)五、故障排除步骤一、污点(Taint)节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点Taint则相反,它使节点能够排斥一类特定的PodTaint和Toleration相互配合,可以用来避免Pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的Pod,是不会被

  10. ruby-on-rails - 是否有针对经验丰富的 Ruby 开发人员的 Rails 指南? - 2

    几年前,我从一些Rails初学者指南开始学习Ruby/Rails。那时我已经学习了Rails的基础知识,例如模型和路由的一些约定优于配置,以及如何使用helpers等。但是,我并没有坚持多久,因为此后不久我发现了Sinatra,并决定我个人更喜欢它。不过,我最终真的爱上了Ruby,从那以后我写了很多Ruby,几乎没有一个是针对任何Rails项目的。然而,事实证明大部分可用的Ruby工作都是针对Rails应用程序的。所以我现在想再尝试一下Rails。现在,该引用资料很棒并且有很多有用的信息,但我只查看了我需要的特定内容的引用资料,而没有记住。但我不太可能在引用资料中看到像script/c

随机推荐