前面我们创建了可以使用的pod,但是当我们要去访问的时候却不知道该怎么访问了,这里就引入了service。
先看下之前使用的pod;
apiVersion: v1 kind: Pod metadata: name: test2 labels: app: web spec: containers: - name: nginx image: 192.168.56.201:5000/nginx:1.13 ports: - containerPort: 80 - name: busybox image: 192.168.56.201:5000/busybox:latest imagePullPolicy: IfNotPresent command: ["sleep", "3600"] ports: - containerPort: 80
查看pod信息,这里面的IP是容器内部IP,在宿主机上是无法访问的,如果是通过docker创建容器的话还可以使用端口映射来进行访问,那么在k8s中如何访问容器内的应用呢?那就是service,通过service不仅解决了应用访问的问题,还实现了负载均衡和服务发现的功能。
定义一个service:
apiVersion: v1 kind: Service metadata: name: myservice spec: type: NodePort ports: - port: 80 nodePort: 30000 targetPort: 80 selector: app: myweb
这个service的意思是定义一个名叫myservice的service,其中端口映射的类型为NodePort,把容器的80端口映射为service的80端口,并把service的80端口映射到宿主机(其实是整个集群)的的30000端口,其中这个30000宿主机端口的范围是可以在apiserver的配置文件中自定义的,同时给这个service定义一个app=myweb的selector选择器。
可以看到定义好的service被随机分配了一个IP地址10.254.141.28,相当于是这个service的VIP,这个时候service和pod还没有任何关联,此时去访问宿主机的30000端口是没有任何响应的,
要是pod与service进行关联可以通过lables,
修改该标签与myservice的标签一致。
可以看到myservice里面的endpoints已经添加进了一个pod,该pod即为test2,但是可以看到其实myservice的labels是none,而selector是app=myweb,其实已经是为pod添加一个selector为app=myweb才是正确的,但是不知道为什么这样做也是可以的,可能在pod中labels和selector是有关系的。
现在通过curl命令也是可以正常访问了。但是这里有的时候可能会因为kube-proxy的问题导致有些node会访问不通,其实在这里应该是用任意一个node的IP:30000都是可以访问的。
下面为了演示服务发现和负载均衡的功能,我使用rc来进行测试。
apiVersion: v1 kind: ReplicationController metadata: name: test2 spec: replicas: 3 selector: app: myweb template: metadata: labels: app: myweb spec: containers: - name: myweb image: 192.168.56.201:5000/nginx:1.13 ports: - containerPort: 80
前面讲过rc可以保证一定副本数的pod正常运行。
我们定义该rc的selector为app=myweb,此时可以猜到myservice里面endpoints里应该是有这三个pod的,
也是可以正常访问的。
此时我们减少一个pod,service里面的endpoints应该就会减少一个。
由于我本身的环境问题导致kube-proxy出现问题,无法做负载均衡的实验,后面再补充,读者也可以自行验证。