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