一、快速開始
1、啟動一個簡單的容器。
一旦在container中打包好應用並將其commit為image之后,你就可以將其部署在k8s集群上。
一個簡單的nginx服務器例子:
先決條件:你需要擁有的是一個部署完畢並可以正常運行的k8s集群。
在Master節點上使用kubectl命令來啟動一個運行着nginx服務器的容器:
$ kubectl run my-nginx --image=nginx --replicas=2 --port=80
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
my-nginx my-nginx nginx run=my-nginx 2
以上命令會讓節點上的Docker從nginx這個image上啟動一個容器監聽80端口,此為一個pod。
而replicas=2則表示會起兩個一模一樣的pod。
使用以下命令來查看創建的pod:
$
kubectl get po
NAME READY STATUS RESTARTS AGE
my-nginx-l8n3i 1/1 Running 0 29m
my-nginx-q7jo3 1/1 Running 0 29m
NAME READY STATUS RESTARTS AGE
my-nginx-l8n3i 1/1 Running 0 29m
my-nginx-q7jo3 1/1 Running 0 29m
k8s會確保你的應用是一直運行的,當容器運行失敗時,k8s會自動重啟容器,當整個節點失敗時,會在另外一個健康的節點啟動這個容器。
2、通過端口將應用連接到Internet上。
先決條件:擁有公網IP,或者在雲服務器上,如:阿里雲,亞馬遜雲等。
以下命令將上一步驟中的nginx容器連接到公網中:
$ kubectl expose rc my-nginx --port=80 --type=LoadBalancer
NAME LABELS SELECTOR IP(S) PORT(S)
my-nginx run=my-nginx run=my-nginx 80/TCP
rc即Replication Controller,上一步驟中的命令其實會自動創建一個名為my-nginx的rc來確保pod的數量維持在2個。
可以使用以下命令來查看rc:
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
my-nginx my-nginx nginx run=my-nginx 2
expose命令將會創建一個service,將本地(某個節點上)的一個隨機端口關聯到容器中的80端口。
可以使用以下命令來查service:
$ kubectl get svc my-nginx
NAME LABELS SELECTOR IP(S) PORT(S)
my-nginx run=my-nginx run=nginx 10.254.110.117 80/TCP
type指明這個svc將會起到一個負載均衡的作用,會將流量導入兩個pod中。
svc會分配一個虛擬IP用來訪問容器,如上步驟中分配的IP為10.254.110.117,則可以在任意節點上通過curl 10.254.110.117得到nginx的歡迎界面。
在分配虛擬IP的過程中,你可能需要等待一些時間。
在任一節點上使用netstat -tunpl命令可以看到,kube-proxy監聽的端口多了一個,端口號是隨機的,可以在瀏覽器中輸入該節點的公網IP:端口訪問放nginx的歡迎界面。
3、刪除容器。
刪除rc,即刪除該rc控制的所有容器。
刪除svc,即刪除分配的虛擬IP。
$
kubectl delete rc my-nginx
replicationcontrollers/my-nginx
$ kubectl delete svc my-nginx
services/my-nginx
replicationcontrollers/my-nginx
$ kubectl delete svc my-nginx
services/my-nginx
注意,如果使用delete pod ${podName}來刪除是沒有效果的,因為rc會馬上啟動另外一個pod來維持總數量為2。
二、通過配置文件來創建資源。
除了某些強制性的命令,如:kubectl run或者expose等,會隱式創建rc或者svc,k8s還允許通過配置文件的方式來創建這些操作對象。
通常,使用配置文件的方式會比直接使用命令行更可取,因為這些文件可以進行版本控制,而且文件的變化和內容也可以進行審核,當使用及其復雜的配置來提供一個穩健、可靠和易維護的系統時,這些點就顯得非常重要。
在聲明定義配置文件的時候,所有的配置文件都存儲在YAML或者JSON格式的文件中並且遵循k8s的資源配置方式。
kubectl可以創建、更新、刪除和獲得API操作對象,當前apiVersion、kind和name會組成一個API Path以供kubectl來調用。
1、通過一個配置文件來啟動容器。
k8s的pod中運行容器,一個包含簡單的Hello World容器的pod可以通過YAML文件這樣來定義:
apiVersion: v1
kind: Pod
metadata:
containers:
- name: hello
image: "ubuntu:14.04"
kind: Pod
metadata:
name: hello-world
spec:
# 當前pod內容的聲明
restartPolicy: Never
containers:
- name: hello
image: "ubuntu:14.04"
command: ["/bin/echo","hello”,”world"]
創建的pod名為metadata.name的值:hello-world,該名稱必須是唯一的。
spec的內容為該pod中,各個容器的聲明:
restartPolicy:Never表示啟動后運行一次就終止這個pod。
containers[0].name為容器1的名字。
containers[0].image為該啟動該容器的鏡像。
containers[0].command相當於Dockerfile中定義的Entrypoint,可以通過下面的方式來聲明cmd的參數:
command: ["/bin/echo"]
args: ["hello","world"]
使用以下命令來通過這個YAML文件創建pod:
$
kubectl create -f ./hello-world.yaml
pods/hello-world
pods/hello-world
2、檢驗配置文件的正確性。
當你不確定聲明的配置文件是否書寫正確時,可以使用以下命令要驗證:
$ kubectl create -f ./hello-world.yaml --validate
使用--validate只是會告訴你它發現的問題,仍然會按照配置文件的聲明來創建資源,除非有嚴重的錯誤使創建過程無法繼續,如必要的字段缺失或者字段值不合法,不在規定列表內的字段會被忽略。
點此查看完成的字段列表:
3、環境變量和變量擴展。
因為並不是所有的image都包含有shell,所以k8s並不會自動執行shell命令,如果你想在容器的shell中執行一些命令,例如擴展環境變量,你可以這么定義配置文件:
apiVersion: v1
kind: Pod
metadata:
name: hello-world
containers:
- name: hello
image: "ubuntu:14.04"
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/sh","-c"]
kind: Pod
metadata:
name: hello-world
spec:
restartPolicy: Never
containers:
- name: hello
image: "ubuntu:14.04"
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/sh","-c"]
args: ["/bin/echo \"${MESSAGE}\""]
但是,如果只是擴展一些環境變量就使用shell是不必要的,所以上面的聲明並不會讓k8s在啟動pod的時候執行,如果你真的想要達到這種效果請使用以下聲明代替:
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
更多的設置環境變量的語法:
4、查看pod狀態。
你可以通過get命令來查看被創建的pod。
如果執行完創建pod的命令之后,你的速度足夠快,那么使用get命令你將會看到以下的狀態:
$
kubectl get pods
NAME READY STATUS RESTARTS AGE
NAME READY STATUS RESTARTS AGE
hello-world 0/1 Pending 0 0s
一個pod剛被創建的時候是不會被調度的,因為沒有任何節點被選擇用來運行這個pod。
調度的過程發生在創建完成之后,但是這個過程一般很快,所以你通常看不到pod是出於unscheduler狀態的除非創建的過程遇到了問題。
pod被調度之后,分配到指定的節點上運行,這時候,如果該節點沒有所需要的image,那么將會自動從默認的Docker Hub上pull指定的image,一切就緒之后,你就可以看到pod是處於running狀態了:
$
kubectl get pods
NAME READY STATUS RESTARTS AGE
NAME READY STATUS RESTARTS AGE
hello-world 1/1 Running 0 5s
其中READY字段表示該pod中 正在運行的容器數量/總容器數量。
由於我們創建的pod是只運行一次就終止,所以在它運行起來之后,它就會馬上終止了,再次查看pod狀態結果如下:
$
kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world 0/1 ExitCode:0 0 15s
NAME READY STATUS RESTARTS AGE
hello-world 0/1 ExitCode:0 0 15s
5、查看pod輸出。
你可能會有想了解在pod中執行命令的輸出是什么,和Docker logs命令一樣,kubectl logs將會顯示這些輸出:
$
kubectl logs hello-world
hello world
6、刪除pod。
當你查看完輸出之后,就可以將這個pod刪除了:
$
kubectl delete pod hello-world
pods/hello-world
和create一樣,delete成功之后會打印出被刪除的資源類型/資源名。
也可以使用資源類型/資源名的格式刪除:
$
kubectl delete pods/hello-world
pods/hello-world
被終止的pod不會馬上自動刪除,所以你可以通過觀察pod的最終狀態是什么,來確認是否需要清理刪除你的那些掛掉的pod。
另外,為了釋放節點上的磁盤空間,刪除pod時容器和它們的日志信息會被一起自動刪除。
