kubernetes-Service

1、前言

我们不应该期望Kubernetes Pod是健壮的,而是要假设Pod中的容器很可能因为各种原因发生故障而死掉。Deployment等Controller会通过动态创建和销毁Pod来保证应用整体的健壮性。换句话说,Pod是脆弱的,但应用是健壮的。每个Pod都有自己的IP地址。当Controller用新Pod替代发生故障的Pod时,新Pod会分配到新的IP地址。这样就产生了一个问题:如果一组Pod对外提供服务(比如HTTP),它们的IP很有可能发生变化,那么客户端如何找到并访问这个服务呢?Kubernetes给出的解决方案是Service。

2、基本语法

2.1 Service yaml

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: httpd-demo-1
  namespace: test
  labels:
    app: httpd-demo
spec:
  selector:
    app: httpd-demo
  ports:
  - port: 80
    protocol: TCP

2.2 关键字段

  • selector:选择器。selector是一个键值对,用于指定Service要代理的Pod的标签。Service会自动检测满足selector条件的Pod,并将流量转发给它们。
  • ports:用于定义Service所使用的端口。这个字段是一个对象,其中包含多个字段,最常用的两个字段是port和targetPort

2.3 port、nodePort、targetPort、containerPort字段说明

port是暴露在cluster ip上的端口,:port提供了集群内部客户端访问service的入口,即clusterIP:port。

nodePort提供了集群外部客户端访问service的一种方式,:nodePort提供了集群外部客户端访问service的端口,即nodeIP:nodePort提供了外部流量访问k8s集群中service的入口。

targetPort是pod上的端口,从port/nodePort上来的数据,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。

containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。

3、Service 类型

3.1 ClusterIP

Service通过Cluster内部的IP对外提供服务,只有Cluster内的节点和Pod可访问,这是默认的Service类型。

3.2 NodePort

将Service通过指定的Node上的端口暴露给外部,访问任意一个 NodeIP:nodePort都将路由到ClusterIP。

端口范围:30000-32767,可以不指定,k8s会生成一个nodePort

3.3 LoadBalancer

使用云平台的负载均衡器向外部公开 Service。Kubernetes 不直接提供负载均衡组件; 你必须提供一个,或者将你的 Kubernetes 集群与某个云平台集成。

3.4 ExternalName

将服务映射到 externalName 字段的内容(例如,映射到主机名 api.foo.bar.example)。 该映射将集群的 DNS 服务器配置为返回具有该外部主机名值的 CNAME 记录。 集群不会为之创建任何类型代理。

4、无头服务(Headless Services)

service 有一个特别的形态就是 Headless Service。service 创建的时候可以指定 clusterIP:None,告诉 K8s 说我不需要 clusterIP(就是刚才所说的集群里面的一个虚拟 IP),然后 K8s 就不会分配给这个 service 一个虚拟 IP 地址,它没有虚拟 IP 地址怎么做到负载均衡以及统一的访问入口呢?

它是这样来操作的:pod 可以直接通过 service_name 用 DNS 的方式解析到所有后端 pod 的 IP 地址,通过 DNS 的 A 记录的方式会解析到所有后端的 Pod 的地址,由客户端选择一个后端的 IP 地址,这个 A 记录会随着 pod 的生命周期变化,返回的 A 记录列表也发生变化,这样就要求客户端应用要从 A 记录把所有 DNS 返回到 A 记录的列表里面 IP 地址中,客户端自己去选择一个合适的地址去访问 pod。

无头 Service 不会获得集群 IP,kube-proxy 不会处理这类 Service, 而且平台也不会为它们提供负载均衡或路由支持。你可以使用无头 Service 与其他服务发现机制交互,而不必绑定到 Kubernetes 的实现。

5、访问service

启动demo

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: httpd-demo-1
  namespace: test
  labels:
    app: httpd-demo
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: httpd-demo

---

apiVersion: v1
kind: Service
metadata:
  name: httpd-demo-2
  namespace: test
  labels:
    app: httpd-demo
spec:
  type: NodePort
  ports:
  - nodePort: 32181
    port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: httpd-demo

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-demo
  namespace: test
  labels:
    app: httpd-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: httpd-demo
  template:
    metadata:
      labels:
        app: httpd-demo
    spec:
      containers:
      - name: httpd-demo
        image: httpd:latest
ini 复制代码
kubectl --kubeconfig=xxx apply -f service.yaml  

启动一个busybox镜像的pod,方便连接service进行测试

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox-test
  namespace: test
  labels:
    app: busybox
spec:
  containers:
  - name: busybox-test
    image: busybox:latest
    command: ["/bin/sh", "-c"]
    args:
    - |
      sleep 100000

查看当前service

scss 复制代码
kubectl --kubeconfig=xxx get svc -n test

NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
httpd-demo-1                  ClusterIP   10.30.99.106    <none>        80/TCP         1h
httpd-demo-2                  NodePort    10.30.167.74    <none>        80:32181/TCP   1h

通过nodeIp:nodePort访问 http://xx.xx.xx.xx:32181/

集群内访问 curl 10.30.99.106:80

其他pod访问

bash 复制代码
kubectl --kubeconfig=xxx exec -it -n test busybox-test sh

# 通过clusterIp访问service
wget -O- 10.30.99.106
# 通过环境变量访问service
wget -O- $HTTPD_DEMO_1_SERVICE_HOST
# 通过服务名访问service,如果是不同namespace,加上.namaspace
wget -O- httpd-demo-1
wget -O- httpd-demo-1.test

# 查看环境变量,可以看到写入了很多环境变量,如xxx_SERVICE_HOST xxx_PORT
env |grep HTTPD_DEMO

参考

相关推荐
oneslide2 小时前
Kubernetes环境部署Redis集群
redis·容器·kubernetes
企鹅侠客2 小时前
k8s之Headless浅谈
云原生·容器·kubernetes
喜欢你,还有大家3 小时前
Kubernetes-架构安装
架构·kubernetes·云计算
庸子5 小时前
Kubernetes调度器深度解析:从资源分配到亲和性策略的架构师之路
java·算法·云原生·贪心算法·kubernetes·devops
easy_coder5 小时前
超越故障修复:从 Kubernetes POD 崩溃到 AI 驱动的运维认知重构
云原生·架构·kubernetes·云计算
mit6.82411 小时前
[Column] How Databricks Implemented Intelligent K8s Load Balancing
云原生·容器·kubernetes
7***533416 小时前
免费的云原生学习资源,K8s+Docker
学习·云原生·kubernetes
拾心211 天前
【云运维】Kubernetes安装(基于 Docker + Calico)
运维·docker·kubernetes
victory04311 天前
K8S NFS PVC PV 挂载点路径问题
云原生·容器·kubernetes
小毅&Nora1 天前
【云计算】【Kubernetes】 ① K8S的架构、应用及源码解析 - 核心架构与组件全景图
架构·kubernetes·云计算