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

简介: 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


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
2月前
|
JSON Kubernetes Linux
Linux环境签发CA证书和K8s需要的证书
Linux环境签发CA证书和K8s需要的证书
29 0
|
9月前
|
Dragonfly 缓存 Kubernetes
Dragonfly 在 Kubernetes 多集群环境下分发文件和镜像
Dragonfly 在 Kubernetes 多集群环境下分发文件和镜像
Dragonfly 在 Kubernetes 多集群环境下分发文件和镜像
|
17天前
|
存储 运维 Kubernetes
构建高效稳定的容器化运维环境:Docker与Kubernetes的协同
【4月更文挑战第14天】 在当今快速发展的云计算时代,容器技术以其轻量级、快速部署和易于管理的优势,成为现代应用交付的标准。本文将深入探讨如何通过Docker和Kubernetes的整合使用来构建一个高效且稳定的容器化运维环境。我们将分析Docker容器的基本概念,探索Kubernetes在容器编排方面的强大能力,以及两者结合所带来的益处。文章还将讨论在实际部署中可能遇到的挑战,并提出相应的解决方案。
|
4月前
|
Kubernetes Linux 数据安全/隐私保护
k8s安装环境准备:Virtualbox安装CentOS;复制多个CentOS虚拟机
k8s安装环境准备:Virtualbox安装CentOS;复制多个CentOS虚拟机
59 0
|
5月前
|
Kubernetes Docker 容器
Kubernetes学习笔记-Part.08 安装k8s环境
Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退
59 2
|
5月前
|
Kubernetes Linux 开发工具
Kubernetes学习笔记-Part.05 基础环境准备
Part.01 Kubernets与docker Part.02 Docker版本 Part.03 Kubernetes原理 Part.04 资源规划 Part.05 基础环境准备 Part.06 Docker安装 Part.07 Harbor搭建 Part.08 K8s环境安装 Part.09 K8s集群构建 Part.10 容器回退
43 1
|
5月前
|
Kubernetes 虚拟化 开发者
Win环境中 Minikube 创建 Kubernetes 集群
Minikube 提供了一个方便的方式,在本地计算机上快速搭建一个小型的 Kubernetes 集群。这个集群是一个单节点的 Kubernetes 集群,包括主节点(control plane)和工作节点(node),运行在虚拟机中。
45 1
|
5月前
|
Kubernetes 测试技术 开发工具
云效我标签只有测试环境:但我其实对应了两个k8s集群(测试A,测试B)环境,这种情况怎么处理呢?
云效我标签只有测试环境:但我其实对应了两个k8s集群(测试A,测试B)环境,这种情况怎么处理呢?
117 1
|
7月前
|
Kubernetes 开发工具 Docker
kubernetes环境从docker迁移到containerd
kubernetes环境从docker迁移到containerd
|
8月前
|
存储 Kubernetes 应用服务中间件
Kubernetes(k8s)环境部署 2
Kubernetes(k8s)环境部署
57 0

推荐镜像

更多