k8s学习-Service(概念、模板、创建、外部代理、删除等)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: k8s学习-Service(概念、模板、创建、外部代理、删除等)

什么是Service?

Service可以简单的理解为逻辑上的一组Pod,一种可以访问Pod的策略,而且其他Pod可以通过这个Service访问到这个Service代理的Pod。相对于Pod而言,它会有一个固定的名称,一旦创建就固定不变。Kubernetes 为 Pods 提供自己的IP地址,并为一组 Pod 提供相同的DNS名, 并且可以在它们之间进行负载均衡。

service在kubectl中可以简写为svc。

无头服务(Headless Service)

在文章k8s学习-StatefulSet(模板、更新、扩缩容、删除等)中提到了Headles Servce,在这里补充上。

有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 “None” 来创建 Headless Service。

可以使用 Headless Service与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。

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

Service的类型

  • ClusterIP:在集群内部使用,也是默认值。
  • ExternalName:通过返回定义的CNAME别名。
  • NodePort:在所有安装了kube-proxy的节点上打开一个端口,此端口可以代理至后端Pod,然后集群外部可以使用节点的IP地址和NodePort的端口号访问到集群Pod的服务。NodePort端口范围默认是30000-32767。
  • LoadBalancer:使用云提供商的负载均衡器公开服务。

注意:需要使用 kube-dns 1.7 及以上版本或者 CoreDNS 0.0.8 及以上版本才能使用 ExternalName 类

型。

创建的dashboard就是NodePort类型的service

可以通过 节点ip:端口号 进行访问。

Service的代理模式

userspace 代理模式

kube-proxy 会监视 Kubernetes 控制平面对 Service 对象和 Endpoints 对象的添加和移除操作。 对每个 Service,它会在本地 Node 上随机打开一个端口。 任何连接到“代理端口”的请求,都会被代理到 Service 的后端 Pods 中的某个上面(按照Endpoints )。 使用哪个后端 Pod,是 kube-proxy 基于 SessionAffinity 来确定的。

最后,它配置 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP) 和 Port 的请求,并重定向到代理端口,代理端口再代理请求到后端Pod。

iptables 代理模式

kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。 对每个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP 和端口的请求,进而将请求重定向到 Service 的一组后端中的某个 Pod 上面。 对于每个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个后端组合。

默认的策略是,kube-proxy 在 iptables 模式下随机选择一个后端。

使用 iptables 处理流量具有较低的系统开销,因为流量由 Linux netfilter 处理, 而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。

如果 kube-proxy 在 iptables 模式下运行,并且所选的第一个 Pod 没有响应, 则连接失败。 这与用户空间模式不同:在这种情况下,kube-proxy 将检测到与第一个 Pod 的连接已失败, 并会自动使用其他后端 Pod 重试。

IPVS 代理模式

在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保IPVS 状态与所需状态匹配。访问服务时,IPVS 将流量定向到后端Pod之一。

IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数, 但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。

IPVS 提供了更多选项来平衡后端 Pod 的流量:

  • rr:轮替(Round-Robin)
  • lc:最少链接(Least Connection),即打开链接数量最少者优先
  • dh:目标地址哈希(Destination Hashing)
  • sh:源地址哈希(Source Hashing)
  • sed:最短预期延迟(Shortest Expected Delay)
  • nq:从不排队(Never Queue)

模板

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc
  name: nginx-svc
spec:
  ports:
  - name: http # Service端口的名称
    port: 80 # Service的端口, service a访问service b,使用http://serviceb
    protocol: TCP # TCP或UDP SCTP 默认: TCP
    targetPort: 80 # 后端应用的端口
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
  selector:   # 筛选器
    app: nginx
  sessionAffinity: None
  type: ClusterIP # Service的类型

上述模板创建一个名为nginx-svc的服务,自己的端口为80、443,将请求代理到端口为80、443,且标签含app=nginx的pod上。

含有selector,会自动创建EndPoint对象(代理外部服务一节会提及)。

实战

创建

创建服务之前,先创建含有标签app=nginx的pod

kubectl get po -n killer --show-labels

命令

kubectl create -f service-nginx.yaml -n killer

结果

访问

命令

curl http://10.110.159.194:80

也可以将ip改为nginx-svc,如果是访问某空间下的service,可以在service名称后加.namespace,例如service-svc.killer

截图

修改

修改为NodePort类型

命令

kubectl edit svc nginx-svc -n killer

结果

修改内容

查看结果

这样外部就可以访问了

代理外部服务

迁移上云/容器化的过程中,可能存在部分上云/容器化,部分仍然在传统的服务器上,这样可以提前创建service去代理外部的服务,例如,web后端的api、mysql、redis等。

我们把前面的yaml文件修改一下,去除一下selector

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
spec:
  ports:
  - name: http # Service端口的名称
    port: 80 # Service的端口, service a访问service b,使用http://serviceb
    protocol: TCP # UDP TCP SCTP default: TCP
    targetPort: 80 # 后端应用的端口
  sessionAffinity: None
  type: ClusterIP

将endpoint导出来

修改为以下yaml

apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx-svc-external
  name: nginx-svc-external
subsets:
- addresses:
  - ip: 110.242.68.4
  ports:
  - name: http
    port: 80
    protocol: TCP

上面的ip是百度的:

分别创建service和对应的endpoint

访问结果如下:

可以看到Service代理了百度的内容,也可以向上面一样,改为NodePort类型,使用浏览器访问进行验证。

代理外部域名

上面的更加通用一点,如果仅仅是域名的话,可以使用ExternalName类型的Service。

我们把前面的yaml修改一下

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-external-domainname
  name: nginx-external-domainname
spec:
  type: ExternalName
  externalName: www.baidu.com

创建后查看一下:

进入同ns下的pod访问一下:

删除

命令

kubectl delete svc nginx-external-domainname -n killer

结果

更多k8s相关内容,请看文章:k8s学习-思维导图与学习笔记

参考

k8s-service

k8s-Pod 与 Service 的 DNS

k8s-使用Service连接到应用

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
存储 Kubernetes 持续交付
k8s学习
【10月更文挑战第1天】
82 4
|
1月前
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
|
1月前
|
Kubernetes 监控 测试技术
k8s学习--基于Ingress-nginx实现灰度发布系统
k8s学习--基于Ingress-nginx实现灰度发布系统
100 2
k8s学习--基于Ingress-nginx实现灰度发布系统
|
14天前
|
存储 Kubernetes 调度
K8S中的核心概念
【10月更文挑战第26天】云原生环境下的安全问题易被忽视,导致潜在风险。应用层渗透测试和漏洞扫描是检测安全的关键,尤其是对于CVE漏洞的修复。然而,常见误解认为安全由外部防护处理且不易引入问题。
|
1月前
|
存储 Kubernetes 调度
|
1月前
|
Kubernetes API 调度
k8s学习--pod的所有状态详解(图例展示)
k8s学习--pod的所有状态详解(图例展示)
136 1
|
1月前
|
Kubernetes 固态存储 调度
k8s学习--如何控制pod调度的位置
k8s学习--如何控制pod调度的位置
|
1月前
|
存储 Kubernetes 调度
k8s学习--k8s群集部署zookeeper应用及详细解释
k8s学习--k8s群集部署zookeeper应用及详细解释
|
运维 Kubernetes Cloud Native
如何轻松学习 Kubernetes?
《深入浅出 Kubernetes》一书共汇集 12 篇技术文章,帮助你一次搞懂 6 个核心原理,吃透基础理论,一次学会 6 个典型问题的华丽操作!
如何轻松学习 Kubernetes?
|
运维 Kubernetes 负载均衡
如何轻松学习 Kubernetes?
本文分享阿里技术专家关于 Kubernetes 的一些观点和看法,并给出学习 Kubernetes 的方法建议 ,最后分享 Kubernetes 集群上的问题排查经验。
11411 0
如何轻松学习 Kubernetes?