k8s Start-up
假設已經有一個docker image 叫 jaysonchiang/posts:0.0.1
Pod 起手式,建立一個 post.yaml
apiVersion: v1
kind: Pod
metadata:
name: posts
spec:
containers:
- name: posts
image: jaysonchiang/posts:0.0.1
apiVersion: v1
K8s ex extensible — we can add in our own custom objects. This specifies the set of objects we want k8s to look at
kind: Pod
指定要建立的 object 的類型
metadata:
Config options for the object we are about to create
name: posts
將這個 Pod 命名為 posts
spec:
實際要應用在這個 object 的屬性
containers:
我們可以在單一個 Pod 裡建立多個 container
- name: posts
將這個 container 命名為 posts
image: jaysonchiang/posts:0.0.1
實際要使用的image。如果不提供版號 0.0.1
那麼會自動被代上 latest
在 cmd 執行 > kubectl apply -f posts.yaml
kubectl get pods
( docker ps
)
kubectl exec -it [podName] [cmd]
(docker exec -it [containerId] [cmd]
)
kubectl logs [podName]
(docker logs [containerId]
)
kubectl delete pod [podName]
kubectl describe pod [podName]
取得執行中的pod的資訊
但我們要用 Deployment object 取代 Pod object,Deployment不但同樣能建立Pod,還能當這個Pod壞掉的時侯,會直接重建一個新的Pod
Deployment 起手式 ,建立 posts-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: posts-depl
spec:
replicas: 1
selector:
matchLabels:
app: posts
template:
metadata:
labels:
app: posts
spec:
containers:
- name: posts
image: jaysonchiang/posts:0.0.1
執行 kubectl apply -f posts-depl.yaml
kubectl get deployments
檢查正在執行的 Deployment
也可以執行 kubectl get pods
看正在執行的 Pod。此時若執行 kubectl delete pod [podName]
。因為Deployment仍在執行中,所以 k8s 會自動再起一個 pod
kubectl describe deployment [depl_name]
kubectl delete deployment [depl_name]
kubectl rollout restart deployment [depl_name]
接著建立 Service,讓 Pod 之間能互相溝通
Service 起手式 ,建立 posts-srv.yaml
apiVersion: v1
kind: Service
metadata:
name: posts-srv
spec:
type: NodePort
selector:
app: posts
ports:
- name: posts
protocol: TCP
port: 4000
targetPort: 4000
Node Port Service目的是要讓 Pod 有一個讓 Cluster 外部訪問的通道。通常只用於開發環境。(如果不指定 type: NodePort
,8ks 預設是 type: ClusterIP
)
其中要注意 port 和 targetPort,分別是對應k8s/Node和對應Pod/Container,為了避免混亂,通常會設定為同一組值。可以看下簡圖:
+--Node---------------------------+
| +--Service---+--Pod---------+ |
+---------+ | | (NodePort) | (Container) | |
| Browser |==> 3xxxx ===> 4000 ===> 4000 | |
+---------+ nodePort | | port | targetPort | |
| +------------+--------------+ |
+---------------------------------+
執行 kubectl apply -f posts-srv.yaml
再執行 kubectl get services
應該會看到下面的結果
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 45h
posts-srv NodePort 10.100.103.230 <none> 4000:32106/TCP 13s
其中的 4000:32106 就是上圖中 Node 內外的Port,代表使用者可以透過瀏覽器走 http://localhost:32106/posts
連到Node
因為我們的 Development 和 Service 是一對一,所以可以寫在同一支 yaml,兩個 object 之間使用 ---
做分格
建立 event-bus-depl.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: event-bus-depl
spec:
replicas: 1
selector:
matchLabels:
app: event-bus
template:
metadata:
labels:
app: event-bus
spec:
containers:
- name: event-bus
image: jaysonchiang/event-bus
---
apiVersion: v1
kind: Service
metadata:
name: event-bus-srv
spec:
selector:
app: event-bus
ports:
- name: event-bus
protocol: TCP
port: 4005
targetPort: 4005
其中的Service 因為沒有指定 type ,所以會是預設的 Cluster IP。Cluster IP的特色是建立一個好記的 URL 給它的 Pod. 而且這組URL只能在 Cluster 內使用。
執行 kubectl apply -f event-bus-depl.yaml
應該可以同時看到 2 object 被建立
同樣,也要仿 event-bus-depl.yaml
在原本的 posts-depl.yaml
增加 ClusterIP 的 object ,並將 metadata
name: posts-clusterip-srv
,避免跟本原本 NodePod object的名稱衝突。(原本的 NodePod object是讓外部Browser連進來用的, 目前仍有存在的必要)
+--Node---------------------------------------------------------+
| |
| +--Pod-------+ +--Pod----------+ |
| | Container |==> | Container | |
| | Posts | Request to | EventBus | |
| +--Service---+ http://event-bus-srv:4005 +--Service------+ |
| | (ClusterIP)| | (ClusterIP) | |
| |posts-clusterip-srv ==>| event-bus-srv | |
| +------------+ +---------------+ |
+---------------------------------------------------------------+
於是 Post Container 可以透過 http://event-bus-srv:4005
發Request 給 EventBus Service,然後EventBus Service 再將訊息傳給 EventBus Pod。
同理,EventBus Pod 裡的 Container 也可以發 Request 到http://posts-srv:4000
給 Pod的Service。
所以 Post Container 所存在的Pod ,其實接了2個 Service:一個是對外的NodePod,一個是對內的 ClusterIP.
因此使用者可以透過瀏覽器,用 http://localhost:3xxxx
發 Request 進到Node。Node內部的Pod也可以透過 http://[cluster-service-name]:port
互相溝通。