目錄
一.YAML文件分析
YAML簡介
- YAML語言的設計目標,就是方便讀寫,它實質是一種通用數據串行化格式,YAML是一種簡潔非標記語言。YAML以數據爲中心,使用空白、縮進,分行組織數據。
- 它的基本語法規則如下:
- 大小寫敏感
- 使用縮進表示層級關係
- 縮進時不允許使用Tab鍵,只允許使用空格鍵
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
- #表示註釋,這個字符一直到行尾都會被解析器忽略
-
YAML的組織結構
YAML文件可以由一個或者多個文檔組成(也即相對獨立的組織結構組成),文檔間使用“---”(三個橫線)在每個文檔開始作爲分隔符。同時,文檔也可以使用“...”作爲結束符(可選)。如果只是單個文檔,分隔符“---”可省略
-
YAML支持的數據結構有三種
- 對象:鍵值對的集合,又稱爲映射(mapping)/哈希(hashes)/字典(dictionary)
- 數組:一組按次序排列的值,又稱爲序列(sequence)/列表(list)
- 純量(scalars):單個的、不可再分的值
對象
- 對象的一組鍵值對,使用冒號結構表示
animal:pets
- YAML也允許另外一種寫法,將所有鍵值對寫成一個行內對象
hash:{name:Steve,foo:bar}
數組
- 一組連詞線開頭的行,構成一個數組
- Cat
- Dog
- Goldfish
- 數據結構的子成員是一個數組,則可以在該項下面縮進一個空格
-
-Cat
-Dog
-Goldfish
-
數組也可以使用行內表示法
animal:[Cat,Dog]
對象與數組的複合結構
- 對象和數組可以結合使用,形成複合結構
languaes:
-Ruby
-Perl
-Python
websites:
YAML:yaml.org
Ruby:ruby-lang.org
Python:python.org
Perl:use.perl.org
純量
- 整數、浮點、字符串、布爾、Null、時間、日期
#整數
age: 10
#浮點
price: 1.48
#字符串
name: Bob
address: Beijing
#布爾值
online:true
#Null
car:-
#時間(IS08601 格式)
time:2019-02-28t21:59:43.10-05:00
#日期(iso8601 格式的年、月、日)
date:2020-05-03
特殊用法
- !!YAML中使用!!做類型強行轉換
yamlbeans包一般用!(單歎號)做類型轉換,snakeyyaml包一般用!!(雙歎號)做類型轉換
string:
- !!str 54321
- !!str ture
#上述命令相當於把數字和布爾類型轉爲字符串。此外允許轉換的類型很多,如下:
---!!list
-Mark McGwire: 65
-Sammy Sosa: 63
-Sammy Sosa: 63
-Ken Griffy: 58
將數組解析爲set,轉化的內容就是:[{ken Griffy=58},{Mark McGwire=65},{Sammy Sosa=63}],重複的Sammy Sosa自動去掉;
- 字符串默認不使用引號表示
str:這是一行字符串
-
字符串之中包含空格或者特殊字符,需要放在引號之中
如果字符串之中包含空格或者特殊字符,需要引導之中,單引號和雙引號都可以用
str:'內容:字符串'
-
雙引號不會對特殊字符轉義
s1:'內容\字符串'
s2:"內容\字符串"
-
單引號之中如果還有單引號,必須連續使用兩個單引號轉義
str:'labor''s day'
-
多行字符串可以使用|保留換行符,也可以使用>摺疊換行
this: |
Foo
Bar
that: >
Foo
bar
-
+表示保留文字塊末尾的換行,-表示刪除字符串末尾的換行
s1: |
Foo
s2: |+
Foo
s3: |-
Foo
-
布爾值用ture或者flase表示
NULL 用~表示
-
錨點&和別名*,可以來引用,定義數據的複用
第一步:使用"&"定義數據的錨點(即要複製的數據)
第二步:使用"*"引用上述錨點數據(即數據的複製目的地)
defaults: &defaults
adapter: postgres
host: localhost
development:
database: myapp_development
<<: *defaults
test:
database: myapp_test
<<: *defaults
## <<表示合併到當前數據,*用來引用錨點
二.deployment.yaml文件詳解
- 查看api版本
[root@master ~]# kubectl api-versions
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
apps/v1beta1
apps/v1beta2
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1
batch/v1beta1
certificates.k8s.io/v1beta1
coordination.k8s.io/v1beta1
events.k8s.io/v1beta1
extensions/v1beta1
networking.k8s.io/v1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
[root@master ~]#
- 編輯YAML文件
##編輯yaml文件時,注意空格數,開頭空出兩個
[root@master demo]# cat nginx-deployment.yaml
apiVersion: apps/v1 #指定api版本
kind: Deployment #指定創建資源的角色/類型
metadata: #定義資源的元數據/屬性
name:nginx-deployment #資源的名字,在同一個namespace中必須唯一
labels: #定義資源的標籤
app: nginx
spec: #指定該資源的內容
replicas: 1 #指定副本數
selector:
matchLabels:
app: nginx #模板名稱
template:
metadata:
labels:
app: nginx
spec: #定義容器模板
containers: #定義容器信息
- name: nginx #容器名
image: nginx:1.15.4 #容器使用的鏡像以及版本
ports:
- containerPort: 80 #容器對外開放的端口
[root@master demo]#
- 使用YAML文件創建資源
#-f指定yaml文件
[root@master demo]# kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
[root@master demo]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-d55b94fd-smrwb 1/1 Running 0 55s
[root@master demo]#
三.Pod YAML文件詳解
- pod yaml文件解析
# yaml格式的pod定義文件完整內容:
# string,表示字符型數據
apiVersion: v1 #必選,版本號,例如v1
kind: Pod #必選,Pod
metadata: #必選,元數據
name: string #必選,Pod名稱
namespace: string #必選,Pod所屬的命名空間
labels: #自定義標籤
- name: string #自定義標籤名字
annotations: #自定義註釋列表
- name: string
spec: #必選,Pod中容器的詳細定義
containers: #必選,Pod中容器列表
- name: string #必選,容器名稱
image: string #必選,容器的鏡像名稱
imagePullPolicy: [Always | Never | IfNotPresent] #獲取鏡像的策略 Alawys表示下載鏡像 IfnotPresent表示優先使用本地鏡像,否則下載鏡像,Nerver表示僅使用本地鏡像
command: [string] #容器的啓動命令列表,如不指定,使用打包時使用的啓動命令
args: [string] #容器的啓動命令參數列表
workingDir: string #容器的工作目錄
volumeMounts: #掛載到容器內部的存儲卷配置
- name: string #引用pod定義的共享存儲卷的名稱,需用volumes[]部分定義的的卷名
mountPath: string #存儲卷在容器內mount的絕對路徑,應少於512字符
readOnly: boolean #是否爲只讀模式
ports: #需要暴露的端口庫號列表
- name: string #端口號名稱
containerPort: int #容器需要監聽的端口號
hostPort: int #容器所在主機需要監聽的端口號,默認與Container相同
protocol: string #端口協議,支持TCP和UDP,默認TCP
env: #容器運行前需設置的環境變量列表
- name: string #環境變量名稱
value: string #環境變量的值
resources: #資源限制和請求的設置
limits: #資源限制的設置
cpu: string #Cpu的限制,單位爲core數,將用於docker run --cpu-shares參數
memory: string #內存限制,單位可以爲Mib/Gib,將用於docker run --memory參數
requests: #資源請求的設置
cpu: string #Cpu請求,容器啓動的初始可用數量
memory: string #內存清楚,容器啓動的初始可用數量
livenessProbe: #對Pod內個容器健康檢查的設置,當探測無響應幾次後將自動重啓該容器,檢查方法有exec、httpGet和tcpSocket,對一個容器只需設置其中一種方法即可
exec: #對Pod容器內檢查方式設置爲exec方式
command: [string] #exec方式需要制定的命令或腳本
httpGet: #對Pod內個容器健康檢查方法設置爲HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #對Pod內個容器健康檢查方式設置爲tcpSocket方式
port: number
initialDelaySeconds: 0 #容器啓動完成後首次探測的時間,單位爲秒
timeoutSeconds: 0 #對容器健康檢查探測等待響應的超時時間,單位秒,默認1秒
periodSeconds: 0 #對容器監控檢查的定期探測時間設置,單位秒,默認10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged:false
restartPolicy: [Always | Never | OnFailure]#Pod的重啓策略,Always表示一旦不管以何種方式終止運行,kubelet都將重啓,OnFailure表示只有Pod以非0退出碼退出才重啓,Nerver表示不再重啓該Pod
nodeSelector: obeject #設置NodeSelector表示將該Pod調度到包含這個label的node上,以key:value的格式指定
imagePullSecrets: #Pull鏡像時使用的secret名稱,以key:secretkey格式指定
- name: string
hostNetwork:false #是否使用主機網絡模式,默認爲false,如果設置爲true,表示使用宿主機網絡
volumes: #在該pod上定義共享存儲卷列表
- name: string #共享存儲卷名稱 (volumes類型有很多種)
emptyDir: {} #類型爲emtyDir的存儲卷,與Pod同生命週期的一個臨時目錄。爲空值
hostPath: string #類型爲hostPath的存儲卷,表示掛載Pod所在宿主機的目錄
path: string #Pod所在宿主機的目錄,將被用於同期中mount的目錄
secret: #類型爲secret的存儲卷,掛載集羣與定義的secre對象到容器內部
scretname: string
items:
- key: string
path: string
configMap: #類型爲configMap的存儲卷,掛載預定義的configMap對象到容器內部
name: string
items:
- key: string
path: string
四.Service yaml文件詳解
- service是kubernetes中的核心概念,通過創建service,可以爲一組具有相同功能的容器應用提供一個統一的入口地址,並且將請求負載分發到後端的各個容器應用之上。
- service YAML文件的相關屬性列表
屬性名稱 | 取值類型 | 是否必選 | 取值說明 |
version | string | Required | v1 |
kind | string | Required | Service |
metadata | object | Required | 元數據 |
metadata.name | string | Required | service名稱,需要符合RFC 1035規範 |
metadata.namespace | string | Required | 命名空間,不指定系統時將使用名爲default的命名空間 |
metadata.labels[] | list | 自定義標籤屬性列表 | |
metadata.annotation[] | list | 自定義註解屬性列表 | |
spec | object | Required | 詳細描述 |
spec.selector[] | list | Requried | Label Selector的配置,將選擇具有指定label標籤的Pod作爲管理範圍 |
spec.type | string | Required |
service的類型,指定service的訪問方式,默認值爲ClusterIP。 1.ClusterIP:虛擬的服務IP地址,該地址用於kuernetes集羣內部的pod訪問,在node上的kube-proxy通過設置iptables規則轉發。 2.NodePort:使用宿主機的端口,使得能夠訪問各個Node的外部客戶端通過Node的IP地址和端口號就能訪問到服務。 3.LoadBalancer:使用外接負載均衡器完成到服務的負載分發,需要在spec.status.loadBalancer字段指定外部負載均衡器的IP地址,並且同時定義nodePort和clusterIp,用於公有云環境 |
spec.clusterIP | string |
虛擬服務IP地址,當type=ClusterIP時,如果不指定,系統自動分配,也可以手工指定;當type=Balancer時,則需要指定。 |
|
spec.sessionAffinity | string |
是否支持Session,可選值爲ClientIP,默認值爲空。 ClientIP:表示將同一個客戶端(根據客戶端的IP地址決定)的訪問請求都轉發到同一個後端Pod |
|
spec.ports[] | list | Service需要暴露的端口列表 | |
spec.ports[].name | string | 端口名稱 | |
spec.ports[].protocol | string | 端口協議,支持TCP和UDP,默認值爲TCP | |
spec.ports[].port | int | 服務監聽的端口號 | |
spec.ports[].targetPort | int | 需要轉發到後端Pod的端口號 | |
spec.ports[].nodePort | int | 當spec.type=NodePort時,指定映射到物理機的端口號 | |
Status | object | 當spec.type=LoadBalancer時,設置外部負載均衡地址,用於公有云環境 | |
status.loadBalancer | object | 外部負載均衡器 | |
status.loadBalancer.ingress | object | 外部負載均衡器 | |
status.loadBalancer.ingress.ip | string | 外部負載均衡器的IP地址 | |
status.loadBalncer.ingress.hostname | string | 外部負載均衡器的主機名 |
- 一般來說,對外提供服務的應用程序需要通過某種機制來實現,對於容器應用最簡單的方式就是通過TCP/IP機制以及監聽IP和端口號來實現
- 編輯service的YAML文件
[root@master demo]# ls
nginx-deployment.yaml nginx-service.yaml
[root@master demo]# cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata: #元數據
name: nginx-service #service的名稱
# namespace: nginx-servcei #命名空間
labels: #自定義標籤屬性
app: nginx
spec: #詳細描述
type: NodePort #service的類型默認爲ClusterIP
ports: #service需要暴露的端口列表
- port: 80
targetPort: 80 #需要轉發到後臺的端口號
selector:
app: nginx
#status: #當spce.type=LoadBalancer時,設置外部負載均衡器的地址
# loadBalancer: #外部負載均衡器
# ingress: #外部負載均衡器
# ip: string #外部負載均衡器的Ip地址值
# hostname: string #外部負載均衡器的主機名
- 使用YAML文件創建service
[root@master demo]# kubectl create -f nginx-service.yaml
service/nginx-service created
[root@master demo]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 7d17h
nginx-service NodePort 10.0.0.187 <none> 80:33856/TCP 8s
[root@master demo]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
nginx-deployment-d55b94fd-smrwb 1/1 Running 0 18m 172.17.60.2 192.168.43.103 <none>
目前kubernetes提供了兩種分發策略:RoundRobin和SessionAffinity
RoundRobin:輪詢模式,即輪詢將請求轉發到後端的各個pod之上
SessionAffinity:基於客戶端IP地址進行會話保持的模式,第一次客戶端訪問後端某個pod之上,之後的請求都轉發到這個pod之上
默認是RoundRobin模式
在某些場景之中,開發人員希望自己控制負載均衡的策略,不使用service提供的默認負載,kubernetes通過Headless Service的概念來實現。
五.ingress:HTTP七層路由機制
- 通常情況下,service和pod僅僅在集羣內部網絡中通過IP地址訪問,所有到達邊界路由器的流量或被丟棄或者轉發到其他地方,
- Ingress是授權入站連接到達集羣服務的規則集合
- 我們可以給Ingress配置提供外部訪問的URL、負載均衡、SSL、基於名稱的虛擬主機,用戶通過POST Ingress資源到API Server的方式來請求ingress。Ingress controller負責實現ingress,通常使用負載平衡器,它還可以配置邊界路由和其他前端,這有助於以HA的方式處理流量
- 如下最簡化的ingress配置
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec: # Ingress spec 中包含配置一個loadbalancer或proxy server
rules: # 的所有信息。最重要的是,它包含了一個匹配所有入站請求的規
- http: # 則列表。目前ingress只支持http規則。
paths:
- path: /testpath # 每條http規則包含以下信息:一個host配置項(比如
# for.bar.com,在這個例子中默認是*),path列表(比
# 如:/testpath),每個path都關聯一個backend(比如
# test:80)。在loadbalancer將流量轉發到backend之前,所有的
# 入站請求都要先匹配host和path。
backend:
serviceName: test # backend是一個service:port的組合。Ingress的流量被轉發到
servicePort: 80 # 它所匹配的backend
- 定義Ingress策略之前需要先部署Ingress Controller,以實現爲所有後端Server都提供一個統一的入口。Ingress Controller需要實現基於不同HTTP URL向後轉發的負載分發規則,並且可以靈活的設置7層負載分發策略。如果公有云服務商能夠提供該類型的HTTP路由LoadBalancer,則可以設置其爲Ingress Controller。
- 在kubernetes中,Ingress Controller將以Pod的形式運行,監控API Server的/ingress接口後端的backend services,如果Service發生變化,則ingress controller應自動更新其轉發規則
- 爲了讓ingress Controller正常啓動,還需要爲它配置一個默認backend,用於在客戶端訪問的URL地址不存在時,返回一個正確的404應答。這個backend服務應用任何應用實現都可以,只要滿足對根路徑”/“的訪問返回404應答,並且提供/healthz路徑以使得kubelet完成對它的健康檢查。
- 對於controller和backend我們暫不創建
- ingress.yaml文件實例
[root@master demo]# cat ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
backend:
serviceName: testsvc
servicePort: 8080
[root@master demo]#
這個Ingress的定義,說明對目標地址http://mywebsite.com/demo的訪問將被轉發到集羣中的service webapp即webapp:8080/demos上。
在Ingress生效之前,需要將webapp服務部署完成。同時需要注意Ingress中的Path的定義,需要與後端真實Service提供的Path一致,否則將被轉轉發到一個不存在的path上,引發錯誤。
六.YAML文件相關測試命令
- 自動測試命令的正確性,並且不執行創建
[root@master demo]# ls
ingress.yaml nginx-deployment.yaml nginx-service.yaml
[root@master demo]# kubectl run nginx-deployment --image=nginx --port=80 --replicas=2 --dry-run
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx-deployment created (dry run)
[root@master demo]#
- 生成yaml文件格式,檢測
[root@master demo]# kubectl run nginx-deployment --image=nginx --port=80 --replicas=2 --dry-run -o yaml
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
run: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: nginx-deployment
spec:
containers:
- image: nginx
name: nginx-deployment
ports:
- containerPort: 80
resources: {}
status: {}
[root@master demo]#
- 查看生成的json格式
[root@master demo]# kubectl run nginx-deployment --image=nginx --port=80 --replicas=2 --dry-run -o json
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
{
"kind": "Deployment",
"apiVersion": "apps/v1beta1",
"metadata": {
"name": "nginx-deployment",
"creationTimestamp": null,
"labels": {
"run": "nginx-deployment"
}
},
"spec": {
"replicas": 2,
"selector": {
"matchLabels": {
"run": "nginx-deployment"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"run": "nginx-deployment"
}
},
"spec": {
"containers": [
{
"name": "nginx-deployment",
"image": "nginx",
"ports": [
{
"containerPort": 80
}
],
"resources": {}
}
]
}
},
"strategy": {}
},
"status": {}
}
[root@master demo]#
- 將現有的資源生成yaml文件,在終端上打印出來
[root@master demo]# kubectl get deploy/nginx-deployment --export -o yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: null
generation: 1
labels:
app: nginx
name: nginx-deployment
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.4
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status: {}
[root@master demo]#
##使用>可以保存到文件中去
- 查看字段幫助信息
kubectl explain pods.spec.containers