今天要說明的是容器的對外連接埠。這裡我們使用NGINX作為測試目標。
首先在邊緣端放置deployments,由它管理3個運行NGINX的Pod,YAML範例如下:
# nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
labels:
app: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deploy
template:
metadata:
labels:
app: nginx-deploy
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
nodeSelector:
name: edge
在YAML檔中指定結點為樹梅派節點,因為同時有PC跟樹梅派的話工作會優先分派給資源較多的節點(PC),所以使用nodeSelector作指定,也就是Kubernetes中最簡單的節點指定方式。有關節點指定的部分後面會再作深入的說明,這裡就先講簡單的:
目前我有四個節點,從圖中可以看到透過KubeEdge加入的節點ROLES會標記為"agent,edge"
要將某些應用部屬在特定節點很簡單,概念上就是先將節點做上記號,稱為label
# 標記節點
# 格式: kubectl label node <節點名稱> <你要加的標籤>=<標籤名>
kubectl label node edge name=edge
標記後可以用show label查看
kubectl get nodes --show-labels
就可以看到對應的標籤已經加上去了。接著部署deployments:
# deploy
kubectl apply -f nginx-deploy.yaml
如同前幾天我們提過的,KubeEdge不支援從雲端直接進入邊緣端的容器中,所以我們在邊緣端裡面先觀察一下運行中的容器
docker ps
可以看到由deployment管理的容器,這時我們需要透過下面的指令取得docker容器IP位址:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-id>
帶入你想查詢的容器id
舉例來說:
得到容器IP之後便可以由本地端訪問容器服務(NGINX):
curl 172.17.0.2:80
當然我們那時候起了3個Pod,另外兩個也可以用同樣的方式存取服務。
小結一下為甚麼特別提出這個點,假如同樣的事情在Kubernetes從級裡面會有甚麼不同呢?
# k8s-nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-nginx-deploy
namespace: default
labels:
app: k8s-nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: k8s-nginx-deploy
template:
metadata:
labels:
app: k8s-nginx-deploy
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
nodeSelector:
name: k8s-node02
可以看到同樣有3個Pod在Kubernetes節點上面起來。但我們存取服務的方式就會簡單很多:
直接透過上面的IP就可以了。但如果類似同樣的情形發生在我早些時候使用的KubeEdge 0.3版本上的話,由於KubeEdge 0.3版本對於容器服務的處理方式是強制對應至node-port,例如NGINX服務佔用的port是80,邊緣端建立Pod時便會將服務對應到邊緣節點上的80 port,連線時直接透過<邊緣節點ip>:80存取;這麼一來如果像今天這樣用deployment同時起了3個同樣使用80 port的Pod就會造成port搶佔,導致同時只會有一個Pod存活。如果你部署服務至邊緣端需要跟本地的容器透過API溝通之類的話,這樣的情況就會限縮服務佈署彈性,算是用過0.3版本升級到1.4版本後一個我覺得蠻有感的改良吧。更多有關容器網路的測試會在之後分享。