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

简介: 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连接到应用

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
1月前
|
存储 运维 Kubernetes
容器服务ACK常见问题之修改service的名字失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
3月前
|
Kubernetes 负载均衡 Perl
kubernetes—五个概念入门(二)
kubernetes—五个概念入门(二)
67 0
|
3月前
|
Kubernetes 应用服务中间件 数据中心
kubernetes—五个概念入门(一)
kubernetes—五个概念入门(一)
78 0
|
4月前
|
Kubernetes 容器
k8s学习-CKS真题-日志审计 log audit
k8s学习-CKS真题-日志审计 log audit
79 0
|
4月前
|
Kubernetes 容器
k8s学习-CKS真题-ImagePolicyWebhook容器镜像扫描
k8s学习-CKS真题-ImagePolicyWebhook容器镜像扫描
113 0
|
3月前
|
Kubernetes 负载均衡 网络协议
|
3月前
|
存储 Kubernetes 调度
Kubernetes 基本概念
Kubernetes 基本概念
60 0
|
2天前
|
存储 Kubernetes Docker
Kubernetes(K8S)集群管理Docker容器(概念篇)
Kubernetes(K8S)集群管理Docker容器(概念篇)
|
2月前
|
Kubernetes 网络协议 API
玩转Kubernetes—基础概念篇
玩转Kubernetes—基础概念篇
58 1
|
3月前
|
Kubernetes iOS开发 Docker
为什么你应该学习 Docker 🐋 和 Kubernetes ☸️?
如果您是一名开发人员,我相信您一定听说过这句话:“它可以在我的机器上运行”。当我们的代码在您的计算机上运行但在朋友的计算机上表现不佳时,这是令人心碎的。
28 0