
Kubernetes | 服务发现
我们平时部署服务的时候需要特别在意服务的IP、端口、协议什么的。
正常情况下服务IP是不会变的,我们只要配置对应的IP就行,或者我们配置一个域名,每次服务改变地址我们都改一下A记录就行。
但是这在k8s里面似乎不大方便,因为我们并不知道各自谁在哪里,节点的IP会随时改变。上一秒你还可以在某个IP找到你的容器,下一秒它就跑了。
服务发现
服务发现就是用某种方法,协助程序发现自己依赖的其他服务的地址和路由。
其实我们上面说的用域名就是服务发现了,只不过还是比较原始,要手工改一下IP。docker里面
而k8s中自带服务发现机制。
k8s
k8s服务编排的最小单位是Pod,一个Pod里面可以运行一个或者多个Container,共用一套CPU、内存、网络资源。可以通过一些Controller,比如说Deployment,来动态部署、实时确保服务运行。
定义Pod后,可以定义一类叫Service的资源。Service就是一个Pod的集合,以及访问这些Pod的策略。
比如说我定义了一个Nginx服务
# from https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
我要从另一个服务里面访问这个服务,就需要再定义一个Service,在k8s中记录这个服务的存在:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 1234
targetPort: 80
这样k8s就会知道,你有一个nginx的app在监听80/tcp,你希望别的服务通过nginx-service这个名字和1234这个端口找到它。
然后当你在同namespace的其他pod中解析nginx时,就可以通过nginx-service:1234来访问这个实例了。在别的namespace中我们也可以用nginx-service.$namespace$比如说nginx-service.default来访问这个nginx,在别的集群上就是需要service.namespace.cluster。
这就是k8s中服务发现最简单的方法。
验证
还记得上一篇博客中,我们用openfaas跑了一个函数叫dig,这个函数解析域名并且返回一个字符串形式表示的IP的JSON列表。忘了的话可以看看这里。
我们在终端中先看一眼我们有哪些函数:
$ kubectl get --namespace openfaas-fn svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dig ClusterIP 10.43.58.194 <none> 8080/TCP 2d13h
nodeinfo ClusterIP 10.43.79.165 <none> 8080/TCP 2d9h
我们看到我们有俩service,一个叫dig,一个叫nodeinfo,就是上一次我们跑的两个fn。
我们在dig中执行一下nodeinfo,就会得到["10.43.79.165"]