1. k8s長時間運行的容器需要滿足什么條件?
如果是立刻可以執行完成,則容器會馬上退出。如果設置容器重啟屬性,則容器會一直不停地重啟。
特別是/bin/bash。
此時需要為容器提供永不完成的任務,如 /bin/bash -c -- "while true; do sleep20; done;"
CMD exec /bin/bash -c "trap : TERM INT; sleep infinity; wait"
apiVersion: v1 kind: Pod metadata: name: ubuntu spec: containers: - name: ubuntu image: ubuntu:latest # Just spin & wait forever command: [ "/bin/bash", "-c", "--" ] args: [ "while true; do sleep 30; done;" ]
參考:如何在Kubernetes上保持運行docker容器,不關閉?
2. 容器優雅啟動和關閉
優雅啟動
很常見的一個場景,一個服務剛啟動,可能會有一堆東西要加載(比如我這邊需要讀數據庫中一堆東西)需要一些時間,而這段時間里,我不希望kubernetes 把請求打到這些還沒初始化的pod上。
kubernetes提供了一個叫探針的東西,可以用來檢測pod是否就緒,只有就緒的情況才會把請求打過來,如果非就緒狀態,這些pod會從service的load balancer中暫時移除。
探針可以是一個command或者是一個HTTP的請求,這邊使用的是一個HTTP請求的形式。需要保證程序在正常情況下可以訪問/heartbeat , 我一般會給這個接口一個success的返回。
readinessProbe: httpGet: path: /heartbeat port: 8001 scheme: HTTP initialDelaySeconds: 30 timeoutSeconds: 1 periodSeconds: 30
以上是一個readiness probe(就緒探針)的一般配置。
- httpGet 使用http get請求作為探針,里邊配置了get請求
- initialDelaySeconds 鈣素kubelet在第一次執行探針之前要等待30秒
- timeoutSeconds 探針超時時間,超過1s則認為探針失敗了
- periodSeconds 探針的執行頻率,默認是1s
- successThreshold:探測失敗后,最少連續探測成功多少次才被認定為成功。默認是 1。對於 liveness 必須是 1。最小值是 1。
- failureThreshold:探測成功后,最少連續探測失敗多少次才被認定為失敗。默認是 3。最小值是 1。
優雅關閉
優雅關閉是指在pod准備關閉時,可能還需要做一些處理,比如保存數據等。這期間服務不會接受新的請求。kubernetes提供了優雅關閉的配置
terminationGracePeriodSeconds: 60
在給pod發出關閉指令時,k8s將會給應用發送SIGTERM信號,程序只需要捕獲SIGTERM信號並做相應處理即可。配置為k8s會等待60秒后關閉。
3. pod狀態
Pod
的status
字段是一個PodStatus
的對象,PodStatus
中有一個phase
字段。
無論是手動創建還是通過Deployment
等控制器創建,Pod
對象總是應該處於其生命進程中以下幾個相位(phase
)之一。
-
掛起(
Pending
):API Server
創建了pod
資源對象已存入etcd
中,但它尚未被調度完成,或者仍處於從倉庫下載鏡像的過程中。 -
運行中(
Running
):Pod
已經被調度至某節點,並且所有容器都已經被kubelet
創建完成。 -
成功(
Succeeded
):Pod
中的所有容器都已經成功終止並且不會被重啟 -
失敗(
Failed
):Pod
中的所有容器都已終止了,並且至少有一個容器是因為失敗終止。即容器以非0
狀態退出或者被系統禁止。 -
未知(
Unknown
):Api Server
無法正常獲取到Pod
對象的狀態信息,通常是由於無法與所在工作節點的kubelet
通信所致。
k8s pod狀態分析參考:https://blog.51cto.com/shunzi115/2449411?source=dra
CrashLoopBackOff: 容器退出,kubelet正在將它重啟
InvalidImageName: 無法解析鏡像名稱
ImageInspectError: 無法校驗鏡像
ErrImageNeverPull: 策略禁止拉取鏡像
ImagePullBackOff: 正在重試拉取
RegistryUnavailable: 連接不到鏡像中心
ErrImagePull: 通用的拉取鏡像出錯
CreateContainerConfigError: 不能創建kubelet使用的容器配置
CreateContainerError: 創建容器失敗
m.internalLifecycle.PreStartContainer 執行hook報錯
RunContainerError: 啟動容器失敗
PostStartHookError: 執行hook報錯
ContainersNotInitialized: 容器沒有初始化完畢
ContainersNotReady: 容器沒有准備完畢
ContainerCreating:容器創建中
PodInitializing:pod 初始化中
DockerDaemonNotReady:docker還沒有完全啟動
NetworkPluginNotReady: 網絡插件還沒有完全啟動
4. k8s容器什么時候更新
k8s容器什么時候更新,怎樣確保image更新后生成最新的pod?每次k8s restart pods時都會重新生成pod嗎?
每次k8s restart pod時都會基於新的image生成新的pod。
5. node宕機后,pod驅離
當node宕機時,希望該node節點上的pod能夠快速疏散到其他節點,並提供服務。測試發現,要等待5分鍾,上面的pod才會疏散。
網上介紹通過修改 /etc/kubernetes/manifests/kube-controller-manager.yaml
- --node-monitor-grace-period=10s - --node-monitor-period=2s - --pod-eviction-timeout=10s
然而驗證不生效。
[root@node-01 testnginx]# kubectl describe pod nginx-deployment|grep -i toleration -A 2 Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: <none> -- Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: <none>
[root@node-01 testnginx]# cat test-nginx.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: my-nginx spec: replicas: 2 template: metadata: labels: app: my-nginx spec: tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 2 - key: "node.kubernetes.io/not-ready" operator: "Exists" effect: "NoExecute" tolerationSeconds: 2 containers: - name: my-nginx image: nginx ports: - containerPort: 443