Contents

Kubernetes 操作 Pod 小記

記錄

使用前建議使用Install and Set Up kubectl | Kubernetes
方便操作指令使用

小記知識

K8s 最小運算單原,一個 Pod 可以跑多個 Container。

  • Pod
  • Pod Controllers

一個 Pod 可以共享的有

  • 網路( IP Address, Port , routing system)
  • 儲存(可以選擇相同儲存空間)
  • IPC(Inter Process Communication)

05:08 補圖(相同網路,內部是127.0.0.1)

Container 狀態

  • Running
  • Terminated 執行完成(成功或失敗)
  • Waiting 還沒跑起來

Pod 狀態

  • Pending 還沒有起來
  • Running 程式運行中
  • Successed 執行成功
  • Failed 執行失敗
  • Unknown

Pods 重啟機制

  • Never
  • Always 總是重啟
  • OnFailure 失敗重啟

Node Affinity 靠近
Node taints 遠離

Control Plane 不能部屬 Pod (No Schedule)
kubeadm 預設情況下不能部屬 Pod 在 Control Plane

可以設定標籤(Label,NodeSelector)

建立 Pod(Imperative Commands)

Imperative Commands 通常測試開發才會使用。正式部屬不建議這樣使用。

1
2
kubectl run kuard --generator=run-pod/v1 --image=gcr.io/kuar-demo/kuard-amd64:blue
# Flag --generator has been deprecated, has no effect and will be removed in the future.

kubectl常用命令 | 好好学习的郝
kubectl –generator 参数被弃用问题解决_沧夜-CSDN博客
kubectl 的用法约定 | Kubernetes

啟動完會看到 pods 有成功

1
2
3
kubectl get pods
# NAME    READY   STATUS    RESTARTS   AGE
# kuard   1/1     Running   0          12s

運行 Pod

1
kubectl apply -f kuard-pod.yaml 

移除 Pod

1
2
3
4
# 使用
kubectl delete pods kuard
# 刪除 pods
kubectl delete -f kuard-pod.yaml 

轉發 port

1
2
3
4
5
6
7
8
# 本地轉發
kubectl port-forward kuard 8080:8080    
# Forwarding from 127.0.0.1:8080 -> 8080
# Forwarding from [::1]:8080 -> 8080

# 對外來原 IP 轉發
kubectl port-forward kuard 8080:8080 --address 0.0.0.0 
# Forwarding from 0.0.0.0:8080 -> 8080

更多可參考kubectl Port-Forward - Kubernetes Port Forwarding Guide

http://IP:8080
就能訪問環境頁面

查看 log

1
kubectl logs kuard

exec 執行程式

1
2
kubectl exec kuard ifconfig
kubectl exec kuard ip a

跟 docker 操作方式差不多

我注意到kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

1
kubectl exec kuard -- ls -l

容器複製檔案

1
kubectl cp  <file-spec-src> <file-spec-dest>

Kubectl Reference Docs

使用中有看到錯誤

1
2
3
4
kubectl cp kuard:/kuard ./kuard                                                                             ✔  26  23:09:09 
# tar: removing leading '/' from member names
ls
# kuard

有看到tar錯誤,後來 ls 有看到檔案
修復kubectl cp出現tar: Removing leading `/’ from member names - 雲+社區 - 騰訊雲
Kubectl cp gives “tar: removing leading ‘/’ from member names” warning · Issue #58692 · kubernetes/kubernetes
原來是 bug …

健康檢查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5      # initialDelaySeconds 字段告訴 kubelet 在執行第一次探測前應該等待 5 秒
      periodSeconds: 5            # periodSeconds 字段指定了 kubelet 應該每 5 秒執行一次存活探測

在這個配置文件中,可以看到 Pod 中只有一個容器。
periodSeconds 字段指定了 kubelet 應該每 5 秒執行一次存活探測。
initialDelaySeconds 字段告訴 kubelet 在執行第一次探測前應該等待 5 秒。
kubelet 在容器內執行命令 cat /tmp/healthy 來進行探測。 如果命令執行成功並且返回值為 0,kubelet 就會認為這個容器是健康存活的。 如果這個命令返回非 0 值,kubelet 會殺死這個容器並重新啟動它。

有兩種 Liveness, Readiness
上面是配置存活、就绪和启动探测器 | Kubernetes範例

1
kubectl apply -f https://k8s.io/examples/pods/probe/exec-liveness.yaml

liveness,readiness 後面會在做整理

如果使用 Liveness Probe,當錯誤發生時 (無回應或回應錯誤),k8s 會嘗試重新建立 (kill then create) 一個新的容器。

如果使用 Readiness Probe,當錯誤發生時,對應的 Service 物件就會將該容器標示為不可使用,所以任何的需求都不會導向該容器。
可先看Day 24 - 常見問題與建議 (5) - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天

Liveness Probe 啟動時候,web 可能會有延連時間。例如有些程式啟動不可能馬上出現內容
這時候 initialDelaySeconds 設定就很重要

Readiness Prob 啟動時候,Service 會算到 Pod 可用,會把當下 Container IP 加到 Service。
配置 Pod 的 liveness 和 readiness 探針 ‧ Kubernetes Handbook - Kubernetes中文指南/雲原生應用架構實踐手冊 by Jimmy Song(宋淨超)

資源限制

Request,Limit

为容器和 Pods 分配 CPU 资源 | Kubernetes

Minikube需要安裝 metrics-server

1
2
3
4
5
minikube addons enable metrics-server

kubectl get apiservices
# NAME
# v1beta1.metrics.k8s.io

創建一個 namespace

1
kubectl create namespace cpu-example
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr
    image: vish/stress
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"
    args:
    - -cpus
    - "2"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml --namespace=cpu-example

kubectl get pod cpu-demo --namespace=cpu-example
# 可以看到 limit 有限制
# 輸出顯示 Pod 中的一個容器的 CPU 請求為 500 milli CPU,並且 CPU 限制為 1 個 CPU。
# resources:
#   limits:
#     cpu: "1"
#   requests:
#     cpu: 500m



NAME       CPU(cores)   MEMORY(bytes)   
cpu-demo   1006m        2Mi     
1
kubectl delete namespace cpu-example

Volumes

Volumes | Kubernetes

其他

相關 YAML API 文件
Kubernetes API Reference Docs

taint

1
2
3
4
# 看Taints: 狀態
kubectl describe 
# 移掉 noschedule 狀態(可以在 Control Pane 操作)
kubectl taint node k8s-dev node-role.kubernetes.io/master:NoSchedule-

建立 Pod(Imperative Object)

使用 Yaml或 JSON 格式寫設定。

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/

1
2
3
4
5
6
7
8
kubectl create -f xxxx.yml
kubectl edit pod xxxx
# 手動更改 yaml
# (覆蓋檔案會友先前檔案執行的yaml不一致,,不實用)
kubectl replace -f xxxx.yml
kubectl get pod xxxx -o yaml > new.yml
# 修改 new.yml
kubectl replace -f xxxx.yml

建立 Pod(Declarative Object)

前面提到 Imperative Object kubectl replace 會有當下資源不一致,原因kubectl create 不會計紀錄,但是kubectl apply 會記錄你每次傳指令yaml檔案內容,所以kubectl apply 不會有像 replace 一樣問題。

所以釐清kubectl apply 和 kubectl create 還是有差異的,書中提到用 kubectl apply就對了XD

Pod & Pause Container

  1. 基於 network namespace 實作網路隔離化
  2. kubeadm 我發現 container 控制元件都是使用 host network namespace,所以跟主機IP一樣

Pod 所有container 都是使用第一個建立 container,docker實作如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
docker run -d --name=ubuntu1 dersimn/netutils  tail -f /dev/null
docker run -d --name=ubuntu2 --net=container:ubuntu1 dersimn/netutils  tail -f /dev/null

## 下面兩個指令你會看到 IP 都相等
docker exec ubuntu1 ifconfig
docker exec ubuntu2 ifconfig
# eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
#         inet 172.18.0.2  netmask 255.255.0.0  broadcast 172.18.255.255
#         ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)
#         RX packets 9  bytes 1046 (1.0 KB)
#         RX errors 0  dropped 0  overruns 0  frame 0
#         TX packets 0  bytes 0 (0.0 B)
#         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
#         inet 127.0.0.1  netmask 255.0.0.0
#         loop  txqueuelen 1000  (Local Loopback)
#         RX packets 0  bytes 0 (0.0 B)
#         RX errors 0  dropped 0  overruns 0  frame 0
#         TX packets 0  bytes 0 (0.0 B)
#         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# ubuntu1 刪掉 container ,ubuntu2 也會連帶刪除

docker rm -f ubuntu1
docker exec ubuntu2 ifconfig
# lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
#         inet 127.0.0.1  netmask 255.0.0.0
#         loop  txqueuelen 1000  (Local Loopback)
#         RX packets 0  bytes 0 (0.0 B)
#         RX errors 0  dropped 0  overruns 0  frame 0
#         TX packets 0  bytes 0 (0.0 B)
#         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# 獨立 ip
docker run -d --name=ubuntu3 --net=host  dersimn/netutils

也可用hwchiu/netutils: Docker image contains useful network tools

簡短的說,Container網路共用同網卡問題,砍掉1,2就會看不到。
這邊你看到刪除container1 後 container2 IP就會不見,依照這個狀況下,K8S網路連線這是一個很大問題,所以使用Pause Container

Pause Container
Pod 起來就會背景睡眠,CNI會掛載到Pause Container
讓你container 1 掛掉不會影響其他 container 2 網路

Workload/Pod Controller

  1. ReplicaSet
  2. Deployment
  3. Daemonset
  4. StatefulSet
  5. Job
  6. CronJob

ReplicaSet

Kubernetes 的 ReplicaSet

kubectl plugin

kubectl 可以放置應用程式在usr/local/bin放置kubectl-*,這邊用 ls 看例子。

例如

放置 /usr/local/bin/kubectl-xxxx
可執行 kubectl xxxx

1
2
3
sudo cp /bin/ls  /usr/local/bin/
kubectl ls 
# 顯示當前路徑

安裝 krew

  1. 安裝 Git
  2. 執行 Installing · Krew裡面指令
  3. 加入 krew 還境變數
  4. 重啟 bash/zsh

Krew 管理 Plugin 套件

1
kubectl krew install tree
1
2
3
4
5
6
7
kubectl tree -n kube-system  ds kindnet
# NAMESPACE    NAME                                     READY  REASON  AGE
# kube-system  DaemonSet/kindnet                        -              14d
# kube-system  ├─ControllerRevision/kindnet-5b547684d9  -              14d
# kube-system  ├─Pod/kindnet-74l9s                      True           14d
# kube-system  ├─Pod/kindnet-kcwbr                      True           14d
# kube-system  └─Pod/kindnet-zrzkp                      True           14d

Deployment

Kubernetes 的 Deployment