kubernetes-service 概述
简介
在一个集群中,我们可以直接访问 pod.
但是当节点死亡时 (或 pod 消失), Pod 随之死亡,此时控制器会自动建具有不同 IP 的新 Pod.
service 就解决了这个问题。
service 是一种抽象,它定义并指向了一组 Pod (endpoints).
创建时,将为每个服务分配一个唯一的 IP 地址 (cluster IP)。此地址与服务的生命周期相关联,并且一般不会更改。
可以将 Pod 配置为与服务通信,服务将自动负载均衡到其中某个 Pod。
也就是说,服务是沟通集群外界和 pod 群组的桥梁。
相关命令
以 nginx-svc 这个服务为例
简单的 yaml 文件如下
1 | apiVersion: v1 |
创建
kubectl apply -f nginx-svc.yaml
获取
kubectl get svc my-nginx
描述
kubectl describe svc my-nginx
编辑
kubectl edit scv my-nginx
访问服务
内部访问
在集群内部,访问 service 主要通过 2 种方式:环境变量和 DNS
比如 linux 自带的环境变量,就是在 env 文件里定义好变量名和服务域名 (IP), 写死的.
DNS 是由 coreDNS 负责解析的,每个 service 会自带一个名字 name, 这个 name 由如下规则定义域名
即 <name>.<namespace>.svc.cluster.local
例如一个叫 collector 的名字的服务,ns 为 juice, 则 dns 为
collector.juice.svc.cluster.local
注意,这个 dns 只能在 pod 里使用
外部访问
如果是从集群外部访问,我们可以通过两种方式:NodePorts 和 LoadBalancer
NodePorts 好配置,Loadbalancer 就是生产环境的内容了,不了解.
还有一个 ingress 也可以用来访问服务,不过这个是另一个对象,相当于服务的再抽象,这里不多说 (反正我暂时用不到).
当节点有 externalIP (也就是所在的机器节点的 IP 地址) 时,我们只需要简单创建服务即可从外部访问
如下为示例的 yaml 文件
1 | apiVersion: v1 |
如上,我们只需要指定 nodeport 或者 load-balancer 即可
此时我们通过 curl https://<EXTERNAL-IP>:<NODE-PORT> -k
即可访问
这个 ExternalIP 是什么呢?
先说结论:
ExternalIP 可以简单理解为公网 IP, 即物理机器对外的 IP 地址。这是和硬件绑定的,k8s 不能创建 ExternalIP.
这个公网是相对的,比如如果是一个学校的局域网 IP, 那这个就是在学校内的 "公网 IP", 而不是校外的公网.
调查 ExternalIP
首先在 k8s 官网可以找到这么一句话
其中 external-ip 是你的服务的外部 IP 地址(LoadBalancer Ingress)
英文版的是这样的
ExternalIP: Typically the IP address of the node that is externally routable (available from outside the cluster).
都说的很含糊
然后搜索引擎,只能找到这种答复
只有公有云上才有ExternalIP
ExternalIP 是公网IP
裸金属众所周知都是<None>
并且,某些 plugin 会判断 InternalIP 和 ExternalIP, 产生不同的结果
那么 k8s 是怎么发现的呢?通过找到这篇文章 , 发现了源码层面的奥义 (这里就不搬运了,源码分析可以自己去原文看)
以下为部分原文
首先,InternalIP是可以被指定的,kubeadm 的init带有一个参数--node-ip让你去指定它。所谓InternalIP实际上就是指Kubernetes集群内部可以被直接访问的Node的IP地址,那么ExternalIP呢?按照定义,它只是在集群外部可路由的,但是Kubernetes并没有规定它到底应该是什么。它把这个字段的设置或者说实现,交给了Cloud Provider,云供应商。
需要特别特别强调的是,不要看到云供应商就以为是公有云,实际上也可以是OpenStack或者vSphere。云供应商需要符合CPI接口规范去开发插件,在Kubernetes的Github组里你可以搜到各种cloud-provider-xxx。
在 OpenStack 的源码里可以找到 ExternalIP
对应的定义
- 本地环境时,这个 IP 是虚拟机创建的时候指定的参数
- 云环境时,这个 IP 是云服务提供商指定的,也就是公网 IP
ExternalIP 不是 k8s 自己的,可以简单理解为公网 IP, 在本地环境时是虚拟机硬件层面的东西
服务发现
//todo