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

参考

相关推荐
YCyjs2 小时前
K8S群集调度二
云原生·容器·kubernetes
Hoxy.R2 小时前
K8s小白入门
云原生·容器·kubernetes
景天科技苑13 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge14 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇14 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
昌sit!1 天前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis1 天前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
北漂IT民工_程序员_ZG1 天前
k8s集群安装(minikube)
云原生·容器·kubernetes
2301_806131361 天前
Kubernetes的基本构建块和最小可调度单元pod-0
云原生·容器·kubernetes
SilentCodeY1 天前
containerd配置私有仓库registry
容器·kubernetes·containerd·镜像·crictl