1. 程式人生 > 實用技巧 >04 . kubernetes資源清單YAML入門

04 . kubernetes資源清單YAML入門

YAML

通過k8s操作yaml配置檔案在node上建立資源,yaml配置檔案就像船垛,用來操控docker這艘大船

yam是專門用來寫配置檔案的語言,非常簡潔和強大。而實際上使用yaml配置檔案建立這些操作物件的方式會比直接使用命令列更可取,因為這些檔案可以進行版本控制,而且檔案的變化和內容也可以進行稽核,當使用及其複雜的配置來提供一個穩健、可靠和易維護的系統時,這些點就顯得非常重要。

在宣告定義配置檔案的時候,所有的配置檔案都儲存在YAML或者JSON格式的檔案中並且遵循k8s的資源配置方式。kubectl可以建立、更新、刪除和獲得API操作物件,當前apiVersion、kind和name會組成一個API Path以供kubectl來呼叫。

使用YAML用於K8s的定義帶來的好處:

# 便捷性:不必新增大量的引數到命令列中執行命令
# 可維護性:YAML檔案可以通過源頭控制,跟蹤每次操作
# 靈活性:YAML可以建立比命令列更加複雜的結構
YAML語法規則
# 1. 大小寫敏感.
# 2. 使用縮排表示層級關係.
# 3. 縮排時不允許使用Tab鍵,只允許使用空格set ai.
# 4. 縮排的空格數不重要,只要相同層級的元素左側對齊即可.
# 5. 表示註釋,從這個字元一直到行尾,都會被解析器忽略.
# 在Kubernetes中,只需要知道兩種結構型別:
# 例一.Maps: 對映即字典Kye: Value
---
apiVersion: v1
kind: Pod
# ---為可選的分隔符,當需要在一個檔案中定義多個結構的時候就需要使用 # 例二.lists列表即陣列
# python中的列表: args=[beijing,shaohai,shenzhen,guangzhou]
args:
- beijing
- shanghai
- shenzhen
- guangzhou
# 可以指定任何數量的項在列表中,每個項的定義以(-)開頭,並且與父元素之間存在縮排

一個簡單的Hello World容器Pod可以通過YAML這樣定義

cat hello.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
spec:
containers:
- name: hello
image: daocloud.io/library/centos:7
command: ["/bin/echo","hello","world"] # apiVersion: v1
# API群組名稱和版本,由組名+版本號組成: group/version,如果group省略表示核心組的定義: 可用$kubectl api-versions獲取;
# 所有的對映資料都可以使用花括號,所有列表資料都得使用中括號.
# apiVersion:piserver版本,建立任何資源都是需要定義的,大部分用v1,但v1不支援deployment,用v1的擴充套件版extensions/v1beta1
# metadata.name: Pod名,該名稱必須是唯一的.
# spec: 當前Pod內容的宣告.
# restartPollcy: Never標識啟動後執行一次就終止這個Pod
# containers: name為容器的名字
# container[1]: image為該啟動容器的映象
# containers[2]: command相當於Dockerfile中定義的Entrypoint,通過下列的方式來宣告cmd的引數.
# command: ["/bin/echo"]
# args: ["hello","world"]
使用yaml釋出一個容器化應用

專案描述

1、需要映象,此映象可以來自於官方,開發,或者是自己製作的映象。

2、在k8s叢集中按照 Kubernetes 專案的規範和要求,將映象組織以它能夠"認識"的方式部署此應用。考慮是否做副本,不做副本就以pod方式部署應用;做副本就需要以deployment方式部署應用,而且還需要部署一個service

什麼叫Kubernetes專案能"認識"的方式?

就是使用YAML或者是JSON格式編寫Kubernetes的配置檔案,這是k8s的必備技能

Kubernetes跟Docker等很多專案最大的不同在於它雖然支援使用kubectl run這樣的命令列方式執行容器,但它並不推薦使用此方式,而是希望用YAML檔案的方式來執行容器,即把容器的定義、引數、配置,統統記錄在一個 YAML 檔案中,然後用kubectl create -f 配置檔案的方式把它執行起來。這樣部署應用還有一個最大的優點在於:檔案中記錄了Kubernetes到底"run"了什麼。

部署過程

編寫建立Pod的YAML檔案

YAML 檔案,對應到 k8s 中,就是一個API Object(API 物件)。當你為這個物件的各個欄位填好值並提交給 k8s 之後,k8s 就會負責創建出這些物件所定義的容器或者其他型別的 API 資源.

cat pod-demo.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports:
- containerPort: 5000 kubectl apply -f pod-demo.yaml --validate
# kind:這裡我們建立的是一個Pod,當然根據你的實際情況,這裡的資源型別可以是Deployment,Job,ngress,Service等.
# metadata: 包含了我們定義的Pod的一些meta資訊,比如名稱namespace、標籤等等資訊.
# spec:包括一些containers,storage,volumes,或者其他Kubernetes需要知道的引數,以及諸如是否在容器失敗時重新啟動容器的屬性,
# 你可以在特定KubernetesAP找到完整的Kubernetes Pod的屬性讓我們看一個典型容器的定義.
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
# 我們將上面內容儲存成為Pod.yaml檔案,來建立Pod

查詢Pod的狀態和生命週期事件

kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Node: node2/172.19.0.54
Start Time: Thu, 19 Dec 2019 16:51:44 +0800
Labels: app=web
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"web"},"name":"nginx","namespace":"default"},"spec":{"contain...
Status: Running
IP: 10.244.1.4
IPs:
IP: 10.244.1.4
Containers:
front-end:
Container ID: docker://5b4895a1e08387557a02760b8c49513bc2728476d627677662605b1f09b4103c
Image: nginx
Image ID: docker-pullable://[email protected]:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 19 Dec 2019 16:53:03 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-j9thc (ro)
flaskapp-demo:
Container ID: docker://7d2e0353226f5a36df8384244a8dbcd766bd356ca037a33eb481d4990986fcfc
Image: jcdemo/flaskapp
Image ID: docker-pullable://jcdemo/[email protected]:8dd21e8822e08414c0fe2531c22b575a33da3964e51d39cfa27e7b68520056af
Port: 5000/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 19 Dec 2019 16:52:18 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-j9thc (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-j9thc:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-j9thc #(目標狀態),以目標狀態為準,k8s就用來確保當前狀態無限向目標狀態轉移
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s # 容忍那些汙點.
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned default/nginx to node2
Warning Failed 11m kubelet, node2 Failed to pull image "nginx": rpc error: code = Unknown desc = Get https://registry-1.docker.io/v2/library/nginx/manifests/sha256:189cce606b29fb2a33ebc2fcecfa8e33b0b99740da4737133cdbcee92f3aba0a: net/http: TLS handshake timeout
Normal Pulling 11m kubelet, node2 Pulling image "jcdemo/flaskapp"
Normal Pulled 10m kubelet, node2 Successfully pulled image "jcdemo/flaskapp"
Normal Created 10m kubelet, node2 Created container flaskapp-demo
Normal Started 10m kubelet, node2 Started container flaskapp-demo
Warning Failed 10m (x2 over 11m) kubelet, node2 Error: ErrImagePull
Warning Failed 10m kubelet, node2 Failed to pull image "nginx": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout
Normal BackOff 10m (x2 over 10m) kubelet, node2 Back-off pulling image "nginx"
Warning Failed 10m (x2 over 10m) kubelet, node2 Error: ImagePullBackOff
Normal Pulling 10m (x3 over 11m) kubelet, node2 Pulling image "nginx"
Normal Pulled 10m kubelet, node2 Successfully pulled image "nginx"
Normal Created 10m kubelet, node2 Created container front-end
Normal Started 10m kubelet, node2 Started container front-end
describe解釋
# 名欄位含義 (以Go Template方式過濾指定的資訊—— 查詢Pod的執行狀態(類似docker的inspect))
kubectl get pods nginx --output=go-template --template={{.status.phase}}
Running # 各欄位含義
Name: Pod的名稱
Namespace: Pod的Namespace。
Image(s): Pod使用的映象
Node: Pod所在的Node。
Start Time: Pod的起始時間
Labels: Pod的Label。
Status: Pod的狀態Running、Complete、Pending,就是pod的生命週期。
Reason: Pod處於當前狀態的原因。
Message: Pod處於當前狀態的資訊。
IP: Pod的PodIP
Replication Controllers: Pod對應的Replication Controller。 Containers:Pod中容器的資訊 Container ID: 容器的ID
Image: 容器的映象
Image ID:映象的ID
State: 容器的狀態
Ready: 容器的準備狀況(true表示準備就緒)。
Restart Count: 容器的重啟次數統計
Environment Variables: 容器的環境變數
Conditions: Pod的條件,包含Pod準備狀況(true表示準備就緒)
Volumes: Pod的資料卷
Events: 與Pod相關的事件列
建立一個簡單的Pod
cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx # 如果需要更改這個Pod,修改這個配置檔案要修改的資訊,然後刪除重建
kubectl replace -f pod-demo.yaml --force
kubectl apply -f pod-demo.yaml --force

進入Pod對應的容器內部

kubectl exec -it nginx /bin/bash
# 也可以去node端使用docker命令進入命令,並且exit對容器不會產生影響.
使用yaml建立一個名稱空間
cat namespace.yml
---
apiVersion: v1
kind: Namespace
metadata:
name: ns-monitor
labels:
name: na-monitor
# 元資料習慣帶name,查詢時可以使用名字,但是labels可以不帶,資源之間呼叫時使用標籤. # 建立該資源
kubectl apply -f namespace.yml # 檢視該資源
kubectl get namespaces
NAME STATUS AGE
default Active 47h
kube-node-lease Active 47h
kube-public Active 47h
kube-system Active 47h
ns-monitor Active 21s kubectl describe namespace ns-monitor
Name: ns-monitor
Labels: name=na-monitor
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"labels":{"name":"na-monitor"},"name":"ns-monitor"}}
Status: Active
No resource quota.
No LimitRange resource. # 刪除該資源
kubectl delete -f namespace.yml

YAML建立deployment和service

建立deployment和pod

cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: daocloud.io/library/nginx
ports:
- containerPort: 80

建立service

cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx

YAML資源限制

cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: daocloud.io/library/nginx
resources:
requests:
memory: "64Mi" # 初始記憶體
cpu: "250m"
limits:
memory: "128Mi" # 最大記憶體
cpu: "500m"
# 其實此處的資源限制是跟docker差不多的,可以在docker用docker inspect檢視.