以下內容僅作為測試,為了說明各個對象之間的關系,采用的kubectl run...,生產環境不建議使用;
1. 創建控制器(deployment)並在其下掛載Pod.
Usage:
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]
~]$ kubectl run nginx --image=nginx:1.14-alpine --port=80 --replicas=1
nginx: 控制器名稱
--image: 指定Pod中的容器要基於哪個鏡像運行
--port: Pod中容器的端口
--relicas: 副本數(當副本數沒有達到定義的數量時,比如刪除了某個副本,那么控制器會補全)
查詢Pod是否成功啟動
~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-7689897d8d-t76qv 1/1 Running 0 100m
#查詢控制器deployment
~]$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 1/1 1 1 4h26m
#刪除Pod查看是否會自動補全副本
~]$ kubectl delete pod nginx-deploy-7689897d8d-t76qv
# 查看Pod,發現名字已經改變了,是個新的Pod
~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-7689897d8d-t82wq 1/1 Running 0 100m
# 查看Pod的詳細信息
~]$ kubectl describe pod nginx-deploy-7689897d8d-t82wq
....
2. CoeDns相關說明
當在任何一個節點上運行了一個Pod之后,則集群中的任意一個節點都可直接訪問此Pod的IP地址或此Pod注冊的Service的地址或主機名;
[node2]操作(單獨訪問Pod的IP地址) ~]$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-7689897d8d-t82wq 1/1 Running 0 111m 10.244.2.7 node2 <none> <none> ~]$ curl 10.244.2.7
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Tue, 09 Jun 2020 08:09:19 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes
將deployment發布到Service
Usage:
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]
~]$ kubectl expose deployment nginx --port=80 --target-port=80 --protocol=TCP --type=ClusterIP
注釋:
deployment: 發布出去的類型,這里要發布deployment類型的控制器
nginx: 控制器的名稱
port: service的端口
target-port: 后端Pod的端口
protocol: 使用的協議
type: 默認為ClusterIP,還有NodePort, LoadBalancer, ExternalName
~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 10.99.43.205 <none> 80/TCP 109m
# 查看Service的詳細信息
~]$ kubectl describe svc nginx
Name: nginx
Namespace: default
Labels: run=nginx-deploy
Annotations: <none>
Selector: run=nginx-deploy
Type: ClusterIP
IP: 10.99.43.205
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.2.7:80
Session Affinity: None
Events: <none>
問:為什么要訪問Service的IP地址,不訪問Pod的呢?
答:因為Pod是有生命周期的,且IP地址及主機名都不是固定的,但Service的地址和主機名,不人為刪除Service后重建的話,默認是不會更改的,Service只是服務器上一個ipvs或IPtables規則.
~]$ curl -I 10.99.43.205
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Tue, 09 Jun 2020 08:25:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes
# 啟動一個客戶端容器,試着訪問Service的名稱(nginx),發現也是可以的,因為Pod中的/etc/resolv.conf中默認記錄了CoreDns的地址,一個Service可能是提供給Pod使用的,Pod中默認擁有CoreDns的記錄,所以可以直接訪問名稱;
~]$ kubectl run client image=busybox -it -- /bin/sh
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local localdomain
options ndots:5
/ # wget -O - -q nginx
....
<title>Welcome to nginx!</title>
....
修改service的發布類型為NodePort
NodePort: 可將Service的端口映射到宿主機的端口,使外界可直接訪問;
~]$ kubectl edit svc nginx ..... spec: ..... # 默認創建的時候為ClusterIP類型,可這樣動態修改,亦或創建時通過"type=NodePort"指定(區分大小寫.) type: NodePort .....
~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
nginx ClusterIP 10.99.43.205 <none> 80:31381/TCP 18h
#注釋:
80:是Service的端口.
31381: 是Service映射到宿主機的端口.
訪問驗證,在網頁端輸入http://IP(宿主機IP):31381,即可訪問Service下的deployment下的Pod程序;
3. 動態調整Pod副本數量、及灰度升級、回滾.
Usage:
kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME) [options]
# 增加副本數量至3個.
~]$ kubectl scale --replicas=3 deployment nginx
~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-84cd4b7f95-95h74 1/1 Running 0 80m
nginx-84cd4b7f95-nwpt4 1/1 Running 0 80m
nginx-84cd4b7f95-t7pzf 1/1 Running 0 80m
# 降低副本數量至2個.
~]$ kubectl scale --replicas=2 deployment nginx
NAME READY STATUS RESTARTS AGE
nginx-84cd4b7f95-95h74 1/1 Running 0 80m
nginx-84cd4b7f95-t7pzf 1/1 Running 0 80m
# 灰度升級.
Usage:
kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N [options]
# 變更鏡像
~]$ kubectl set image deployment nginx nginx-deploy=nginx:latest
deployment: 控制器的類型
nginx: 控制器的名稱
nginx-deploy: Pod中容器的名稱,使用"kubectl describe pod Pod名"就可查詢到
nginx:latest: 要變更的鏡像,默認從DockerHub上獲取
# 回滾
Usage:
kubectl rollout SUBCOMMAND [options]
~]$ kubectl rollout undo deployment nginx
總結:
1. Pod是注冊到Service之上的,當Pod作為客戶端訪問另外的Pod時,不使用對方的IP地址,使用Service的名稱或地址;
2. 控制器控制着Pod的副本數量,監控着Pod的狀態,當副本不夠用時,及時補全,當過多時,及時剔除;
3. CoreDns也是有Service的;