一、YAML 基礎
YAML是專門用來寫配置文件的語言,非常簡潔和強大,使用比json更方便。它實質上是一種通用的數據串行化格式。后文會說明定義YAML文件創建Pod和創建Deployment。
YAML語法規則:
- 大小寫敏感
- 使用縮進表示層級關系
- 縮進時不允許使用Tal鍵,只允許使用空格
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
- ”#” 表示注釋,從這個字符一直到行尾,都會被解析器忽略
在Kubernetes中,只需要知道兩種結構類型即可:
- Lists
- Maps
使用YAML用於K8s的定義帶來的好處包括:
- 便捷性:不必添加大量的參數到命令行中執行命令
- 可維護性:YAML文件可以通過源頭控制,跟蹤每次操作
- 靈活性:YAML可以創建比命令行更加復雜的結構
YAML Maps
Map顧名思義指的是字典,即一個Key:Value 的鍵值對信息。例如:
---
apiVersion: v1
kind: Pod
注:---
為可選的分隔符 ,當需要在一個文件中定義多個結構的時候需要使用。上述內容表示有兩個鍵apiVersion和kind,分別對應的值為v1和Pod。
Maps的value既能夠對應字符串也能夠對應一個Maps。例如:
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web
注:上述的YAML文件中,metadata這個KEY對應的值為一個Maps,而嵌套的labels這個KEY的值又是一個Map。實際使用中可視情況進行多層嵌套。
YAML處理器根據行縮進來知道內容之間的關聯。上述例子中,使用兩個空格作為縮進,但空格的數據量並不重要,只是至少要求一個空格並且所有縮進保持一致的空格數 。例如,name和labels是相同縮進級別,因此YAML處理器知道他們屬於同一map;它知道app是lables的值因為app的縮進更大。
注意:在YAML文件中絕對不要使用tab鍵
YAML Lists
List即列表,說白了就是數組,例如:
args -beijing -shanghai -shenzhen -guangzhou
可以指定任何數量的項在列表中,每個項的定義以破折號(-)開頭,並且與父元素之間存在縮進。在JSON格式中,表示如下:
{ "args": ["beijing", "shanghai", "shenzhen", "guangzhou"] }
當然Lists的子項也可以是Maps,Maps的子項也可以是List,例如:
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: flaskapp-demo image: jcdemo/flaskapp ports: 8080
如上述文件所示,定義一個containers的List對象,每個子項都由name、image、ports組成,每個ports都有一個KEY為containerPort的Map組成,轉成JSON格式文件:

{ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "kube100-site", "labels": { "app": "web" }, }, "spec": { "containers": [{ "name": "front-end", "image": "nginx", "ports": [{ "containerPort": "80" }] }, { "name": "flaskapp-demo", "image": "jcdemo/flaskapp", "ports": [{ "containerPort": "5000" }] }] } }
二、使用YAML創建Pod
創建Pod
--- apiVersion: v1 kind: Pod metadata: name: kube100-site labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: flaskapp-demo image: jcdemo/flaskapp ports: - containerPort: 5000
上面定義了一個普通的Pod文件,簡單分析下文件內容:
- apiVersion:此處值是v1,這個版本號需要根據安裝的Kubernetes版本和資源類型進行變化,記住不是寫死的。
- kind:此處創建的是Pod,根據實際情況,此處資源類型可以是Deployment、Job、Ingress、Service等。
- metadata:包含Pod的一些meta信息,比如名稱、namespace、標簽等信息。
- spe:包括一些container,storage,volume以及其他Kubernetes需要的參數,以及諸如是否在容器失敗時重新啟動容器的屬性。可在特定Kubernetes API找到完整的Kubernetes Pod的屬性。
下面是一個典型的容器的定義:
… spec: containers: - name: front-end image: nginx ports: - containerPort: 80 …
上述例子只是一個簡單的最小定義:一個名字(front-end)、基於nginx的鏡像,以及容器將會監聽的指定端口號(80)。
除了上述的基本屬性外,還能夠指定復雜的屬性,包括容器啟動運行的命令、使用的參數、工作目錄以及每次實例化是否拉取新的副本。 還可以指定更深入的信息,例如容器的退出日志的位置。容器可選的設置屬性包括:
name、image、command、args、workingDir、ports、env、resource、volumeMounts、livenessProbe、readinessProbe、livecycle、terminationMessagePath、imagePullPolicy、securityContext、stdin、stdinOnce、tty
了解了Pod的定義后,將上面創建Pod的YAML文件保存成pod.yaml,然后使用Kubectl
創建Pod:
$ kubectl create -f pod.yaml pod "kube100-site" created
可以使用Kubectl命令查看Pod的狀態
$ kubectl get pods NAME READY STATUS RESTARTS AGE kube100-site 2/2 Running 0 1m
注: Pod創建過程中如果出現錯誤,可以使用kubectl describe
進行排查。
創建Deployment
上述介紹了如何使用YAML文件創建Pod實例,但是如果這個Pod出現了故障的話,對應的服務也就掛掉了,所以Kubernetes提供了一個Deployment的概念 ,目的是讓Kubernetes去管理一組Pod的副本,也就是副本集 ,這樣就能夠保證一定數量的副本一直可用,不會因為某一個Pod掛掉導致整個服務掛掉。
--- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kube100-site spec: replicas: 2 template: metadata: labels: app: web spec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: flaskapp-demo image: jcdemo/flaskapp ports: - containerPort: 5000
一個完整的Deployment的YAML文件如上所示,接下來解釋部分內容:
- 注意這里apiVersion對應的值是extensions/v1beta1,同時也需要將kind的類型指定為Deployment。
- metadata指定一些meta信息,包括名字或標簽之類的。
- spec 選項定義需要兩個副本,此處可以設置很多屬性,例如受此Deployment影響的Pod的選擇器等
- spec 選項的template其實就是對Pod對象的定義
- 可以在Kubernetes v1beta1 API 參考中找到完整的Deployment可指定的參數列表
- 將上述的YAML文件保存為deployment.yaml,然后創建Deployment:
三、使用k8s創建應用
關於k8s的安裝,請參考連接:
https://www.cnblogs.com/xiao987334176/p/9947548.html
本文就是基於此鏈接的環境來搭建的。
新建yaml文件
這里使用 jcdemo/flaskapp 鏡像,來介紹,如何創建一個flask應用。
登錄到k8s主控端,也就是master節點。新建文件 flask.yaml
vim flask.yaml
內容如下:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: flaskapp-1 spec: replicas: 1 template: metadata: labels: name: flaskapp-1 spec: containers: - name: flaskapp-1 image: jcdemo/flaskapp ports: - containerPort: 5000 --- apiVersion: v1 kind: Service metadata: name: flaskapp-1 labels: name: flaskapp-1 spec: type: NodePort ports: - port: 5000 name: flaskapp-port targetPort: 5000 protocol: TCP nodePort: 30005 selector: name: flaskapp-1
NodePort方式暴露服務的端口的默認范圍(30000-32767)
大概解釋一下,這個yaml文件。它分為2部分。藍色部分 提供節點,紅色部分 暴露服務
為什么要分為這2部分呢?因為藍色部分,只是在 k8s部署了一個pod 節點。那么它對應的服務,比如flask,外部是不能直接訪問的。
怎么才能訪問呢?必須 暴露服務才行。這就好比下面這個命令!
docker run -it -p 30005:5000 flaskapp-port
使用-p 參數將端口映射出來,其他服務器才能訪問!
這2個參數,就是要暴露的端口號,使用的是TCP協議
protocol: TCP
nodePort: 30005
檢驗配置文件的正確性
kubectl create -f flask.yaml --validate
使用--validate只是會告訴你它發現的問題,仍然會按照配置文件的聲明來創建資源,除非有嚴重的錯誤使創建過程無法繼續,如必要的字段缺失或者字段值不合法,不在規定列表內的字段會被忽略。
可以使用如下命令檢查Deployment的列表:
root@k8s-master001:~# kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE flaskapp-1 1 1 1 0 18s
查看pod狀態
root@k8s-master001:~# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE flaskapp-1-84b7f79cdf-bbp4p 0/1 ContainerCreating 0 27s <none> k8s-node002
提示正在創建中,等待幾秒鍾,再次查看
root@k8s-master001:~# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE flaskapp-1-84b7f79cdf-bbp4p 1/1 Running 0 31s 192.138.6.130 k8s-node002
如果狀態是 Running,並且出現了IP地址,那么表示部署成功了!
如果狀態不是Running,查看日志
kubectl describe po flaskapp-1-84b7f79cdf-bbp4p
如果 出現錯誤,需要解決錯誤,將應用刪除,使用命令
這個是單個pod刪除
kubectl delete pods flaskapp-1-84b7f79cdf-bbp4p
如果需要刪除flaskapp所有的pod,使用命令
kubectl delete -f flask.yaml
如果images更新了,修改yaml文件,重新應用一遍
kubectl apply -f flask.yaml
訪問應用
這個時候,就可以訪問flask頁面了
root@k8s-master001:~# curl http://192.138.6.130:5000/ <html><head><title>Docker + Flask Demo</title></head><body><table><tr><td> Start Time </td> <td>2018-Dec-04 09:25:51</td> </tr><tr><td> Hostname </td> <td>flaskapp-1-84b7f79cdf-bbp4p</td> </tr><tr><td> Local Address </td> <td>192.138.6.130</td> </tr><tr><td> Remote Address </td> <td>192.138.121.64</td> </tr><tr><td> Server Hit </td> <td>2</td> </tr></table></body></html>root@k8s-master001:~#
我想直接使用windows 10訪問flask,可不可呢?
不可以!為什么?因為我的電腦不能直接訪問 192.138.0.0/16 的網絡。這個是k8s的pod 網絡。
添加路由
首先需要在windows 10 中添加路由,比如:k8s主控端的地址為 192.168.0.102
確保cmd打開時,以管理員身份運行,否則提示沒有權限!
在cmd中輸入如下命令:
route add 192.138.0.0 MASK 255.255.0.0 192.168.0.121
設置nat規則
登錄到k8s 主控端,添加一個nat規則。
其中 -s 是你的客戶端網絡,-d 是k8s 的 pod 網絡。-o 指定網卡。tunl0是k8s集群,創建的。
iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -d 192.138.0.0/16 -o tunl0 -j MASQUERADE
使用windos 10 訪問flask頁面,效果如下:
或者使用 http://node_ip:30005 也是可以訪問的。
本文參考鏈接:
https://blog.csdn.net/phantom_111/article/details/79427144