前面我們創建了可以使用的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出現問題,無法做負載均衡的實驗,后面再補充,讀者也可以自行驗證。