記錄
使用前建議使用Install and Set Up kubectl | Kubernetes
方便操作指令使用
小記知識
K8s 最小運算單原,一個 Pod 可以跑多個 Container。
一個 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
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
- 基於 network namespace 實作網路隔離化
- 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
- ReplicaSet
- Deployment
- Daemonset
- StatefulSet
- Job
- 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
- 安裝 Git
- 執行 Installing · Krew裡面指令
- 加入 krew 還境變數
- 重啟 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