k8s--Service 环境准备、ClusterIP 使用

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: k8s--Service 环境准备、ClusterIP 使用

环境准备


在使用 service 之前,首先利用 Deployment 创建出 3 个 pod,注意要为 pod 设置 app=nginx-pod 的标签

创建deployment.yaml,内容如下

apiVersion: apps/v1
kind: Deployment # 类型为 deployment
metadata:
  name: pc-deployment # deployment 的名称
  namespace: zouzou
spec: 
  replicas: 3 # 三个副本
  selector: # 标签选择器
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels: # 标签
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.14
        ports: # 暴露容器的 80 端口
        - containerPort: 80

创建 deployment

[root@dce-10-6-215-215 tmp]# kubectl create -f deployment.yaml
deployment.apps/pc-deployment created

查看 pod 的详情

[root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
nginx3-c5d7c9466-vnt9c           1/1     Running   0          24h   172.29.34.135    dce-10-6-215-200   <none>           <none>
pc-deployment-5bff7844cb-6n65j   1/1     Running   0          51s   172.29.190.159   dce-10-6-215-190   <none>           <none>
pc-deployment-5bff7844cb-vnvhs   1/1     Running   0          51s   172.29.34.223    dce-10-6-215-200   <none>           <none>
pc-deployment-5bff7844cb-z5ks7   1/1     Running   0          51s   172.29.34.255    dce-10-6-215-200   <none>           <none>

为了方便后面的测试,修改下三台 pod 里 nginx 的 index.html 页面

# 使用下面命令依次更改,注意要换成自己的 pod 名称
kubectl exec -it pc-deployment-5bff7844cb-vnvhs -n zouzou /bin/sh
echo "我是 172.29.34.223 的 pod" > /usr/share/nginx/html/index.html

修改完成之后,我们测试一下,看有没有修改成功


ClusterIP 类型的 Service


默认的 Service 类型就是 ClusterIP,它只能在集群内部访问

创建 service-clusterip.yaml 文件

apiVersion: v1
kind: Service  # 类型为 Service
metadata:
  name: service-clusterip # Service 的名称
  namespace: zouzou
spec:
  selector: # 标签选择器,会和上面创建的 deployment.yaml 的 pod 关联起来
    app: nginx-pod
  clusterIP: 172.31.88.88 # service 的 ip 地址,如果不写,默认会生成一个,注意这个地址不能写,有个范围的,我的是 172.31.0.0/16
  type: ClusterIP # 类型为 Service 的 ClusterIP
  ports:
  - port: 8080  # Service 端口,自定义
    targetPort: 80 # pod 端口,不写默认是 80

注意:上面的 service-clusterip.yaml 只是创建一个 service,因为里面的选择器为 app:nginx-pod,所以会和 deployment.yaml 里的 pod 关联起来(因为 deployment.yaml 里的标签也是 app:nginx-pod)

创建 service

# 创建 service
[root@dce-10-6-215-215 tmp]# kubectl create -f service-clusterip.yaml
service/service-clusterip created

查看 service

# 可以看到 CLUSTER-IP 就是我们设置的 IP 地址,端口是我们写的 8080,svc 是 service 的简写
[root@dce-10-6-215-215 tmp]# kubectl get svc -n zouzou -o wide
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE    SELECTOR
service-clusterip   ClusterIP   172.31.88.88   <none>        8080/TCP   2m6s   app=nginx-pod

查看 service 的详细信息,可以看到我们的 Selector 选择的是pod 的标签为 app=nginx-pod 的 pod。还有个参数是 Session Affinity(Session 亲和度),这里为 None,后面在说

还有一个很重要的是 Endpoints,里面有三个 ip 地址,意思就是这个 service 找到了三个 pod,当访问 service 的时候,会转发到这三个里面的其中一个上,其实这三个就是我们上面使用 deployment.yaml 创建的三个 pod

# 查看 service 的详细信息
[root@dce-10-6-215-215 tmp]# kubectl describe svc service-clusterip -n zouzou
Name:              service-clusterip
Namespace:         zouzou
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP:                172.31.88.88
IPFamily:          IPv4
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         172.29.190.159:80,172.29.34.223:80,172.29.34.255:80  # Endpoints 列表,里面就是当前 service 可以负载到的服务入口 
Session Affinity:  None # session 亲和性
Events:            <none>

查看 ipvs 的映射规则

我的有好多,这里找到 service 的 ip 对应的 ip。从下面可以看到,当我们访问 172.31.88.88:8080 的时候,会采用轮询的方式访问下面的三个 ip(也就是我们的 pod),rr 是轮询的意思

[root@dce-10-6-215-215 tmp]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  127.0.0.1:30001 rr
  -> 172.28.116.206:80            Masq    1      0          0
TCP  172.31.88.88:8080 rr # 主要看这个和下面的三个
  -> 172.29.34.223:80             Masq    1      0          0
  -> 172.29.34.255:80             Masq    1      0          0
  -> 172.29.190.159:80            Masq    1      0          0
TCP  172.31.122.40:80 rr
  -> 172.28.116.205:80            Masq    1      0          0

循环访问下我们的 service 地址,看下是不是采用轮询的方式

从下面的结果可以看出来,确实是采用轮询的方式来访问了我们的 pod


使用域名进行访问


Service域名格式:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 为指定的集群的域名

例如上面的就可以写成

service-clusterip.zouzou.svc.cluster.local


Endpoints


Endpoint 是 kubernetes 中的一个资源对象,存储在 etcd 中,用来记录一个 service 对应的所有 pod 的访问地址,它是根据 service 配置文件中 selector 描述产生的。

一个 Service 由一组 Pod 组成,这些 Pod 通过 Endpoints 暴露出来,Endpoints 是实现实际服务的端点集合。换句话说,service 和 pod 之间的联系是通过 endpoints 实现的。

我们可以通过下面的命令查看 Endpoint

# 会返回所有的,因为我这里只有一个 service,所以只有一个
[root@dce-10-6-215-215 tmp]# kubectl get endpoints -n zouzou -o wide
NAME                ENDPOINTS                                             AGE
service-clusterip   172.29.190.159:80,172.29.34.223:80,172.29.34.255:80   20m


负载分发策略


对 Service 的访问被分发到了后端的 Pod 上去,目前 kubernetes 提供了两种负载分发策略:

  • 如果不定义,默认使用 kube-proxy 的策略,比如随机、轮询
  • 基于客户端地址的会话保持模式,即来自同一个客户端发起的所有请求都会转发到固定的一个 Pod 上

此模式可以使在 spec 中添加 sessionAffinity: ClientIP 选项

修改  service-clusterip.yaml ,加上 sessionAffinity: ClientIP

apiVersion: v1
kind: Service  # 类型为 Service
metadata:
  name: service-clusterip # Service 的名称
  namespace: zouzou
spec:
  sessionAffinity: ClientIP # 来自同一个客户端发起的所有请求都会转发到固定的一个 Pod 上
  selector: # 标签选择器,会和上面创建的 deployment.yaml 的 pod 关联起来
    app: nginx-pod
  clusterIP: 172.31.88.88 # service 的 ip 地址,如果不写,默认会生成一个
  type: ClusterIP # 类型为 Service 的 ClusterIP
  ports:
  - port: 8080  # Service 端口,自定义
    targetPort: 80 # pod 端口

在 apply 一下

# 也可以删除 service,在创建
[root@dce-10-6-215-215 tmp]# kubectl apply -f service-clusterip.yaml
service/service-clusterip configured

在来查看下 ipvs 的映射规则,可以看到在我们的 service 后面加了个 persistent,表示持久的,即某一个客户端发起的请求都会分给一个 pod 上

[root@dce-10-6-215-215 tmp]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  127.0.0.1:30001 rr
  -> 172.28.116.206:80            Masq    1      0          0
TCP  172.31.88.88:8080 rr persistent 10800
  -> 172.29.34.223:80             Masq    1      0          0
  -> 172.29.34.255:80             Masq    1      0          0
  -> 172.29.190.159:80            Masq    1      0          0
TCP  172.31.122.40:80 rr
  -> 172.28.116.205:80            Masq    1      0          0

在循环访问下 service,看能不能分给一个固定的 pod

[root@dce-10-6-215-215 tmp]# while true;do curl 172.31.88.88:8080; sleep 5; done;
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod

在用我们的 node 节点访问

[root@dce-10-6-215-200 ~]# while true;do curl 172.31.88.88:8080; sleep 5; done;
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod

从上面的结果可以看出,当我们设置了 sessionAffinity: ClientIP 后,当某个客户端访问 service 的时候,会将这个客户端的请求分给一个固定的 pod


删除 service


通过 yaml 文件删除

kubectl delete -f service-clusterip.yaml

通过 service 的名称删除

kubectl delete svc service-clusterip -n zouzou


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
Kubernetes Cloud Native 容器
完全免费的K8S学习平台:在线集群环境助力你的云原生之路!
完全免费的K8S学习平台:在线集群环境助力你的云原生之路!
396 1
|
3月前
|
Kubernetes Ubuntu Shell
wsl Ubuntu环境 创建 k8s集群
wsl Ubuntu环境 创建 k8s集群
127 0
|
3月前
|
JSON Kubernetes Linux
Linux环境签发CA证书和K8s需要的证书
Linux环境签发CA证书和K8s需要的证书
66 0
|
3月前
|
Kubernetes Java 测试技术
ChaosBlade常见问题之在K8s环境下演练cpu满载报错如何解决
ChaosBlade 是一个开源的混沌工程实验工具,旨在通过模拟各种常见的硬件、软件、网络、应用等故障,帮助开发者在测试环境中验证系统的容错和自动恢复能力。以下是关于ChaosBlade的一些常见问题合集:
172 0
|
3月前
|
存储 数据采集 Kubernetes
一文详解K8s环境下Job类日志采集方案
本文介绍了K8s中Job和Cronjob控制器用于非常驻容器编排的场景,以及Job容器的特点:增删频率高、生命周期短和突发并发大。文章重点讨论了Job日志采集的关键考虑点,包括容器发现速度、开始采集延时和弹性支持,并对比了5种采集方案:DaemonSet采集、Sidecar采集、ECI采集、同容器采集和独立存储采集。对于短生命周期Job,建议使用Sidecar或ECI采集,通过调整参数确保数据完整性。对于突发大量Job,需要关注服务端资源限制和采集容器的资源调整。文章总结了不同场景下的推荐采集方案,并指出iLogtail和SLS未来可能的优化方向。
131 1
|
24天前
|
Kubernetes Linux 调度
k8s环境设置-pod下载及重启策略
k8s环境设置-pod下载及重启策略
32 1
|
2月前
|
Prometheus 监控 Kubernetes
深入理解Prometheus: Kubernetes环境中的监控实践
Kubernetes简介 在深入Prometheus与Kubernetes的集成之前,首先简要回顾一下Kubernetes的核心概念。Kubernetes是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。它提供了高度的可扩展性和灵活性,使得它成为微服务和云原生应用的理想选择。 核心组件 • 控制平面(Control Plane):集群管理相关的组件,如API服务器、调度器等。 • 工作节点(Nodes):运行应用容器的机器。 • Pods:Kubernetes的基本运行单位,可以容纳一个或多个容器。
|
2月前
|
消息中间件 Kubernetes Android开发
消息队列 MQ产品使用合集之如何在kubernetes环境里面部署
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
2月前
|
前端开发 Devops 测试技术
阿里云云效产品使用问题之更换所部署的环境关联的ACK集群该如何实现
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
3月前
|
域名解析 Kubernetes 网络协议
【域名解析DNS专栏】云原生环境下的DNS服务:Kubernetes中的DNS解析
【5月更文挑战第29天】本文探讨了Kubernetes中的DNS解析机制,解释了DNS如何将服务名转换为网络地址,促进集群内服务通信。Kubernetes使用kube-dns或CoreDNS作为内置DNS服务器,每个Service自动分配Cluster IP和DNS条目。通过示例展示了创建Service和使用DNS访问的流程,并提出了优化DNS解析的策略,包括使用高性能DNS解析器、启用DNS缓存及监控日志,以实现更高效、可靠的DNS服务。
59 1