K8s之pod生命周期、Deployment,Service
1、Pod
kubernetes中,最基礎單元就是Pod。Pod主要用來管理容器,通常Pod中包含的是一個調用鏈的服務。例如Nginx 和 Django
1.1、Pod的生命周期
[root@k8s-master-01 k8s]# vim pod.yaml
kind: Pod #指定資源名稱
apiVersion: v1 #資源版本
#創建資源的基礎信息
metadata:
name: test #只能由小寫字母中划線數字組成,
namespace: default #指定部署的命名空間
labels: #標簽
app:pod #隨意定義的標簽
spec: #定義容器
containers: #對象列表 可能會存在多個相同對象(或者說配置項)
- name: nginx #容器名稱
- image: nginx:latest #容器鏡像
# 部署
[root@k8s-master-01 k8s]# kubectl apply -f pod.yaml
pod/testv1 created
# 查看
[root@k8s-master-01 k8s]# kubectl get pods
NAME READY STATUS RESTARTS AGE
testv1 1/1 Running 0 52s
Pod名稱 啟動數量 運行狀態 重啟次數 啟動時間
1.2、Pod的重啟策略(restartPolicy)
當Pod出現了問題時,Pod怎么解決。
Always :無論什么情況下退出,都重啟
OnFailure :只有當非正常情況下退出時,才會重啟
Never :無論什么情況下退出,都不重啟
1.3、Pod中容器的拉取策略(imagePullPolicy)
容器的 imagePullPolicy 和鏡像的標簽會影響 kubelet 嘗試拉取(下載)指定的鏡像。
IfNotPresent : 當本地沒有該鏡像時,下載
Always :無論本地有沒有該鏡像,都去遠程下載
Never :無論本地有沒有該鏡像,都不去遠程下載
kind: Pod
apiVersion: v1
metadata:
name: testv1
spec:
restartPolicy: OnFailure
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
# 刪除Pod
[root@k8s-master-01 k8s]# kubectl delete -f pod.yaml
# 部署Pod
[root@k8s-master-01 k8s]# kubectl apply -f pod.yaml
pod/testv1 created
1.4、靜態Pod和動態Pod之間的區別
靜態Pod:沒有控制器
動態Pod:有控制器 不可抗力宕機 自動重啟
1.5、Pod的回調鈎子
1.5.1、啟動回調
當Pod中所有的容器創建完成之后,立即調用的命令。
執行失敗:如果啟動回調鈎子執行失敗,容器無法進入正常啟動狀態。
exec : 執行命令
kind: Pod
apiVersion: v1
metadata:
name: testv1
spec:
restartPolicy: OnFailure
containers:
- name: nginx
image: nginx:1.18
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command:
- "/bin/sh"
- "-c"
- "echo 'Hello World!' > /root/1.txt"
httpGet : 通過HTTP協議訪問
kind: Pod
apiVersion: v1
metadata:
name: testv1
spec:
restartPolicy: OnFailure
containers:
- name: nginx
image: nginx:1.18
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
httpGet:
port: 80
path: /
host: www.baidu.com
tcpSocket : 通過Ping命令,探測端口
kind: Pod
apiVersion: v1
metadata:
name: testv1
spec:
restartPolicy: OnFailure
containers:
- name: nginx
image: nginx:1.18
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
tcpSocket:
port: 80
host: 106.13.81.75
1.5.2、就緒性檢測
檢測容器是否正常運行。
執行失敗:如果就緒性檢測執行失敗,Pod會立即驅離出負載均衡。
exec : 執行命令
httpGet : 通過HTTP協議訪問
readinessProbe:
httpGet:
port: 80
path: /index
tcpSocket : 通過Ping命令,探測端口
service
1.5.3、存活性檢測(livenessProbe)
檢測容器是否正常啟動。
執行失敗:如果存活性檢測執行失敗,Pod會按照一定時間周期不斷重啟,直至Pod正常啟動。
exec : 執行命令
livenessProbe:
exec:
command:
- "/bin/sh"
- "-c"
- "cat /etc/hostss"
httpGet : 通過HTTP協議訪問
livenessProbe:
httpGet:
port: 8080
path: /
tcpSocket : 通過Ping命令,探測端口
livenessProbe:
tcpSocket:
port: 80
控制器
1.5.4、結束回調
當Pod收到了銷毀指令時,立即執行。
執行失敗:如果結束回調執行失敗,容器依然會終止。
exec : 執行命令
httpGet : 通過HTTP協議訪問
tcpSocket : 通過Ping命令,探測端口
kind: Pod
apiVersion: v1
metadata:
name: testv1
spec:
restartPolicy: OnFailure
containers:
- name: nginx
image: nginx:1.18
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- "/bin/sh"
- "-c"
- "echo 'HelloWorld' > /root/2.txt"
1.6 、查看資源配置項
kubectl explain pod #pod.什么就查看什么的具體命令
kubectl create #創建資源
kubectl get [資源類型] #獲取資源列表
kubectl get [資源類型] -o wide #獲取資源列表詳細信息
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
1.7、標簽
kubectl get pods --show-labels #查看容器的所有標簽
kubectl get pods -l 標簽名=標簽值 #查看指定標簽的容器
kubectl get pods -L 標簽名 #把標簽作為一列顯示出來
#增加一個標簽 資源類型 資源名稱 標簽名=標簽值
kubectl label pod test deploy=stable
#刪除一個標簽 資源類型 資源名稱 標簽名
kubectl label pod test deploy-
2、Deployment無狀態控制器
k8s中所有的控制器都是用來管理Pod的。Deployment支持滾動更新、版本升級等功能。命名空間級資源
2.1、控制器簡介、類型
Deployment為Pod提供聲明式更新。在Deployment對象中描述所需的狀態,然后Deployment控制器將實際狀態以受控的速率更改為所需的狀態。您可以定義部署以創建新的副本集,或刪除現有部署並在新部署中采用其所有資源。一句話:Deployment主要功能是保證有足夠的Pod正常對外提供服務。
無狀態控制器:沒有先后啟動順序,沒有固定節點,沒有固定名稱 ,標簽不變
deployment 是通過標簽來管理pod的
deployment控制器會無限接近理想狀態 刪除或者增加pod
2.1、Deployment案例
kind: Deployment
apiVersion: apps/v1
#創建資源的基礎信息
metadata:
name: test-deployment
spec: #管理pod
selector: # 選擇Pod 標簽選擇器里面有兩種匹配模式詳細看下面的2.5
matchLabels: #精確匹配 標簽
app: test-deployment
template: # 定義創建Pod的模板
metadata:
labels: #標簽 因為Deployment通過標簽管理容器
app: test-deployment
spec: #定義容器
containers:
- name: nginx
image: nginx
#啟動
[root@k8s-master-01 k8s]# kubectl apply -f deployment.yaml
#獲取控制器
[root@k8s-master-01 k8s]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
test-deployment 1/1 1 1 99s
名字 啟動Pod數量 理想狀態 當前狀態 時間
#查看容器
[root@k8s-master-01 k8s]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-deployment-574644b7-f27b9 1/1 Running 0 45s
控制器名字-token-隨機值 啟動
不會重復名字-動態pod
#發現刪除這個容器之后 會自動新建一個
delete pod test-deployment-76cdbc6456-cmwtd
2.2、Deployment動態擴容
[root@k8s-master-01 k8s]# kubectl scale deployment test-deployment --replicas=10
控制器名稱 指定副本數
2.3、Deployment的滾動更新
[root@k8s-master-01 k8s]# kubectl set image deployment/test-deployment nginx=nginx:1.18
設置 鏡像 資源名稱/基礎信息名字 容器名=image版本
deployment.apps/test-deployment image updated
#生成新的容器,舊的先保存 新的生成完成 正常啟動 才會停止舊的 在刪除
#修改鏡像
kubectl edit deployments.apps nginx-deployment
deployment.apps/nginx-deployment edited
2.4、Deployment回滾
# 查看一下部署歷史
[root@k8s-master-01 k8s]# kubectl rollout history deployment test-deployment
deployment.apps/test-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
#根據版本
# 回滾到上一個版本
[root@k8s-master-01 k8s]# kubectl rollout undo deployment test-deployment
deployment.apps/test-deployment rolled back
# 回滾到第一個版本(指定版本)
[root@k8s-master-01 k8s]# kubectl rollout undo deployment test-deployment --to-revision=1
deployment.apps/test-deployment rolled back
2.5、Deployment中的標簽選擇器
在配置清單中,匹配標簽的方式有兩種:matchLabels 和 matchExpressions
spec: #管理pod
selector:
matchLabels : 精確匹配
matchExpressions : 模糊匹配
-key:app #匹配的是下面的標簽名key
operator: In #匹配的模式 分別有
IN #存在
NOTIN #不存在列表
values:
- "deployment"
- "string1"
#上面這些話表示 標簽名app 對應下面的template 有一個叫app的標簽 並且標簽的值在values里面任意一個都ok
2.6、Deployment的配置詳解
namespace: 命名空間
labels: 標簽
annotations: 注解
replicas: 副本數
kind: Deployment
apiVersion: apps/v1
#創建資源的基礎信息
metadata:
name: test-deployment
spec: #管理pod
selector: # 選擇Pod 標簽選擇器里面有兩種匹配模式詳細看下面的2.5
matchLabels: #精確匹配 標簽
app: test-deployment
template: # 定義創建Pod的模板
metadata:
labels: #標簽 因為Deployment通過標簽管理容器
app: test-deployment
spec: #定義容器
containers:
- name: nginx
image: nginx
2.7、將Django部署到k8s
kind: Deployment
apiVersion: apps/v1
metadata:
name: django
spec:
selector:
matchLabels:
app: django
template:
metadata:
labels:
app: django
spec:
containers:
- name: django
image: alvinos/django:v1.1
3、Service負載均衡器
作用就是為k8s中的Pod提供負載均衡服務。
動態抓取pod的ip
動態移除或添加pod 實現負載均衡效果
3.1、Service實踐
kind: Deployment
apiVersion: apps/v1
metadata:
name: django
spec:
selector:
matchLabels:
app: django
template:
metadata:
labels:
app: django
spec:
containers:
- name: django
image: alvinos/django:v1
---
kind: Service
apiVersion: v1
metadata:
name: test_svc
spec:
selector:
app: django
ports:
- port: 80 #services的端口
targetPort: 80 #容器的端口
name: http
#kubectl get svc
3.2、ClusterIP
只在集群內部訪問。ClusterIP也是默認的Service類型。
---
kind: Service
apiVersion: v1
metadata:
name: django
spec:
selector:
app: django
ports:
- port: 80
targetPort: 80
name: http
type: ClusterIP
clusterIP: 10.96.117.231
3.3、NodePort
利用宿主主機的IP和端口,實現網絡轉發
NodePort是將主機IP和端口跟kubernetes集群所需要暴露的IP和端口進行關聯,方便其對外提供服務。內部可以通過ClusterIP進行訪問,外部用戶可以通過NodeIP:NodePort的方式單獨訪問每個Node上的實例。
---
kind: Service
apiVersion: v1
metadata:
name: django
spec:
selector:
app: django
ports:
- port: 80
targetPort: 80
name: http
nodePort: 30080
type: NodePort
clusterIP: 10.96.117.231
3.4、LoadBalancer
利用公網負載均衡,轉發流量到k8s。
LoadBalancer類型的service 是可以實現集群外部訪問服務的另外一種解決方案。不過並不是所有的k8s集群都會支持,大多是在公有雲托管集群中會支持該類型。負載均衡器是異步創建的,關於被提供的負載均衡器的信息將會通過Service的status.loadBalancer字段被發布出去。
---
kind: Service
apiVersion: v1
metadata:
name: django
spec:
selector:
app: django
ports:
- port: 80
targetPort: 80
name: http
nodePort: 30080
type: LoadBalancer
clusterIP: 10.96.117.231
3.5、ExternalName
將外部的服務接入集群,使用k8s來管理外部的服務。
ExternalName Service是Service的一個特例,它沒有選擇器,也沒有定義任何端口或Endpoints。它的作用是返回集群外Service的外部別名。它將外部地址經過集群內部的再一次封裝(實際上就是集群DNS服務器將CNAME解析到了外部地址上),實現了集群內部訪問即可。例如你們公司的鏡像倉庫,最開始是用ip訪問,等到后面域名下來了再使用域名訪問。你不可能去修改每處的引用。但是可以創建一個ExternalName,首先指向到ip,等后面再指向到域名。
---
kind: Service
apiVersion: v1
metadata:
name: externalname
spec:
type: ExternalName
externalName: www.baidu.com
3.6、Service別名
Service別名 跟 Service IP 同樣的功能。
Service別名的組成:
service名稱.命名空間.svc.cluster.local
django.default.svc.cluster.local
4、案例
4.1、數據庫
---
kind: Namespace
apiVersion: v1
metadata:
name: mysql
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysql
namespace: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
readinessProbe:
tcpSocket:
port: 3306
---
kind: Service
apiVersion: v1
metadata:
name: mysql
namespace: mysql
spec:
ports:
- port: 3306
targetPort: 3306
selector:
app: mysql
[root@k8s-master-01 ~]# kubectl apply -f mysql.yaml
[root@k8s-master-01 ~]# kubectl exec -it -n mysql mysql-566544f8cc-8w6zz -- bash
root@mysql-566544f8cc-8w6zz:/# mysql -uroot -p123456
mysql> create database bbs CHARACTER SET utf8 COLLATE utf8_general_ci;;
Query OK, 1 row affected (0.00 sec)
4.2、BBS
---
kind: Namespace
apiVersion: v1
metadata:
name: bbs
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: bbs
namespace: bbs
spec:
selector:
matchLabels:
app: bbs
template:
metadata:
labels:
app: bbs
spec:
containers:
- name: bbs
image: alvinos/django:v1.3
readinessProbe:
tcpSocket:
port: 80
---
kind: Service
apiVersion: v1
metadata:
namespace: bbs
name: bbs
spec:
selector:
app: bbs
ports:
- port: 80
targetPort: 80
nodePort: 30081
type: NodePort
[root@k8s-master-01 k8s]# kubectl apply -f bbs.yaml