Kubernetes(K8S)概述
-
Kubernetes又稱作k8s,是Google在2014年發布的一個開源項目。
-
最初Google開發了一個叫Borg的系統(現在命名為Omega),來調度近20多億個容器。 在積累了數十年的經驗后,Google決定重寫這個容器管理系統,並貢獻給開源社區, 而這個系統就是Kubernetes。它也是Omega的開源版本。
-
從2014年第一個版本發布以來,迅速得到了開源社區的追捧,目前,k8s已經成為了 發展最快、市場占有率最高的容器編排引擎產品。
-
Kubernetes中文社區 | 中文文檔 https://www.kubernetes.org.cn/k8s
安裝minikube
設置阿里雲鏡像
vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
安裝minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
安裝kubectl
curl -LO https://dl.k8s.io/release/v1.20.0/bin/linux/amd64/kubectl
chmod +x ./kubectl #賦予操作權限
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
安裝conntrack
yum install conntrack 我們先操作一波
啟動minikube
minikube start --vm-driver=none --image-mirror-country='cn'
啟動minkube報錯解決
Minikube不能成功啟動的報錯分析及解決方案
Minikube啟動前需要對系統環境進行初始化:啟用docker服務
sudo systemctl enable docker.service關閉防火牆
sudo systemctl stop firewalld關閉內存交換
sudo swapoff -a修改為cgroupfs
cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } EOF重新加載配置
systemctl daemon-reload重啟docker
systemctl restart docker關閉selinux
sudo setenforce 0文件權限
sudo chmod -R 777 /etc/kubernetes/addons/啟動kubelet服務,注意:可能需要第一次允許minikube start后才會拉取kubelet
systemctl enable kubelet.service初始化時的報警:
1.在使用kubeadm init命令初始化節點剛開始時,會有如下的perflight階段,該階段會進行檢查,如果其中出現了如下WARNING並且初始化失敗了。下面會對下述幾個警告進行解決:
kubeadm init ... [init] Using Kubernetes version: v1.15.0 [preflight] Running pre-flight checks [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/ [WARNING FileExisting-socat]: socat not found in system path
WARNING IsDockerSystemdCheck
解決辦法:修改或創建/etc/docker/daemon.json,加入下述內容:{ "exec-opts": ["native.cgroupdriver=systemd"] }重啟docker:
systemctl daemon-reload systemctl restart docker查看修改后的狀態:
docker info | grep Cgroup2.
WARNING FileExisting-socatsocat是一個網絡工具, k8s 使用它來進行 pod 的數據交互,出現這個問題直接安裝socat即可:
yum install -y socat3.
WARNING Firewalld
[WARNING Firewalld]: firewalld is active, please ensure ports [8443 10250] are open or your cluster may not function correctly解決辦法:
##暫時關閉防火牆 systemctl stop firewalld.service ##永久關閉 systemctl disable firewalld.service4.
WARNING Service-Docker
[WARNING Service-Docker]: docker service is not enabled, please run 'systemctl enable docker.service'
解決辦法:systemctl enable docker.service5.
WARNING Service-Kubelet
[WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
解決辦法:systemctl enable kubelet.service6.
WARNING Swap
[WARNING Swap]: running with swap on is not supported. Please disable swap解決辦法:
swapoff -a7.
SELINUX未關閉
Problems detected in kube-addon-manager [13ce287ce3f6]:
error: Error loading config file "/var/lib/minikube/kubeconfig": open /var/lib/minikube/kubeconfig: permission denied
error: Error loading config file "/var/lib/minikube/kubeconfig": open /var/lib/minikube/kubeconfig: permission denied
error: Error loading config file "/var/lib/minikube/kubeconfig": open /var/lib/minikube/kubeconfig: permission denied
解決辦法:setenforce 0或嘗試永久關閉SELINUX
8.
ERROR FileContent–proc-sys-net-bridge-bridge-nf-call-iptables
[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1解決辦法:
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
停止minikube
minikube stop
查看所有deployment
kubectl get deployment
查看所有pod
kubectl get pods
查看節點
[root@VM-12-15-centos download]` kubectl get nodes
NAME STATUS ROLES AGE VERSION
vm-12-15-centos Ready control-plane,master 79m v1.23.1
【解釋】
node是⽤於承載運行中的容器的。
有⼀個node,這個node的角⾊是master。
k8s也有集群的概念,即:cluster,包含master和node,該節點即是master節點,⼜是node節點。
創建nginx的deployment
[root@zhaowa-edu-01 ~]` kubectl create deployment my-nginx --image nginx:latest
deployment.apps/my-nginx created
【解釋】
創建deployment其實有兩種⽅式
1.基於命令行配置運行
kubectl create
kubectl run
- 基於yaml配置文件的
kubectl apply -f xxx.yml
查看所有pod信息以及ip和port
[root@zhaowa-edu-01 ~]` kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
NOMINATED NODE READINESS GATES
my-nginx-b7d7bc74d-jgfks 1/1 Running 0 7m35s 172.18.0.3
zhaowa-edu-01 <none> <none>
查看所有service
[root@zhaowa-edu-01 ~]` kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21h
【解釋】
pod是不穩定的。服務可以保證穩定。
雙十⼀之前,訂單系統需要20個服務實例,雙⼗⼀促銷階段,擴容⾄100個服務實例。雙⼀之后,對服務縮容⾄30個服務實例。
我們是⼀個穩定的請求⽅式,統⼀個ip的。這個就是service的作用。
查詢所有命名空間
[root@zhaowa-edu-01 ~]` kubectl get namespace
NAME STATUS AGE
default Active 21h
kube-node-lease Active 21h
kube-public Active 21h
kube-system Active 21h
【解釋】
默認的就是defalut。
其它kube-*的都是k8s系統⾃⼰的命名空間。
將副本數(pod)從1個修改為3個
[root@zhaowa-edu-01 ~] ` kubectl scale deployments/my-nginx --replicas=3
deployment.apps/my-nginx scaled
[root@zhaowa-edu-01 ~] ` kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
my-nginx 1/3 3 1 19m
[root@zhaowa-edu-01 ~] ` kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-b7d7bc74d-jgfks 1/1 Running 0 19m
my-nginx-b7d7bc74d-r9gsg 0/1 ContainerCreating 0 17s
my-nginx-b7d7bc74d-vr958 0/1 ContainerCreating 0 17s
【解釋】
什么是副本個數?
pod的個數
如果我們不指定副本個數的話,那么默認就是⼀個pod
將副本數(pod)從3個修改為2個
[root@zhaowa-edu-01 ~] ` kubectl scale deployments/my-nginx --replicas=2
deployment.apps/my-nginx scaled
[root@zhaowa-edu-01 ~]` kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
my-nginx 2/2 2 2 22m
[root@zhaowa-edu-01 ~]` kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-b7d7bc74d-jgfks 1/1 Running 0 22m
my-nginx-b7d7bc74d-r9gsg 1/1 Running 0 2m39s
k8s重要概念介紹
| 組件名稱 | 作用 |
|---|---|
| Cluster | 資源的集合。我們的k8s利⽤這些資源運⾏各種基於容器的應用。是計算、存儲和網絡資源的集合 |
| Master | Cluster的⼤腦。司令部。主要的任務就是用來調度的。決定我們的應用應該放到哪⾥去執行。 為了高可⽤,也可以運⾏多個master。職責是運行容器應用。 |
| Node | 來負責運⾏容器應⽤。Node是由Master去管理的,負責監控和容器狀態的匯報。 |
| Pod | k8s的最小工作單元,包含1orN個容器。 Pod的使用方式: ⼀個pod運⾏⼀個容器 最常⽤的就是這種情況。 ⼀個pod運⾏多個容器 ⼀定是非常緊密相關的⼀組容器,並且需要資源的共享。⼀起啟動、⼀起停止。 |
| Controller | k8s通過它來管理Pod 包含:Deployment、ReplicaSet、DaemonSet、StatefulSet、Job。 Deployment就是我們最常⽤的Controller。它可以管理Pod的多個副本。(即:--replicas=3),並且可以確保Pod按照期望的狀態去運⾏。 ReplicaSet它也是管理Pod的多個副本。 我們使⽤deployment的時候,會⾃動的創建ReplicaSet,最終是有ReplicaSet去創建的pod,而我們並不是去直接的使⽤它。 DaemonSet⽤於每個Node最多只運⾏⼀個Pod副本的創建。 StatefulSet保證副本按照固定的順序啟動、更新、刪除。 |
| Service | 為Pod提供了負載均衡、固定的IP和Port pod是不穩定的,ip會變化的。所以我們需要⼀個固定的ip或port。 區別: Controller ——> 負責k8s運行容器的。 Service ——> 負責k8s訪問容器的。 |
| Namespace | 解決同一個Cluster中,如何區別分開Controller、Pod等資源的問題,資源隔離! |
kubernetes架構
k8s架構圖
重要概念
當我們執行部署應用並指定兩個副本的時候,執行流程如下所示:
Kuberctl發送部署請求到API Server。
API Server通知Controller Manager創建一個deployment資源。
Scheduler執行調度任務,將兩個副本Pod分發到node1和node2上。
node1和node2上的kubelet在各自的節點上創建並運行Pod。
k8s架構中,主要是由Master和Node組成的。
下面我們來針對這兩部分進行詳細的介紹。
Master
- API-Server
屬於前端交互接⼝。提供基於Http/https RESTful API。
接收對應的指令。
- Scheduler
負責決定將pod放到那個Node上去運⾏的。
- Controller Manager
⾮常關鍵的組件。管理Cluster中的各種資源。
- etcd
負責保存k8s的配置信息和各種資源的狀態信息。
如果數據發⽣了變化,etcd會快速通知相關的組件。
Node
- kubelet
創建和運⾏容器。
- kube-proxy
負責我們請求的轉發。
如果對於多個副本,它會實現負載均衡。
Deployment
創建資源的方式
- 方式一
用kubectl命令直接創建。
比如:kubectl run nginx-deployment--image=nginx:1.7.9--replicas=2
在命令行中通過參數指定資源的屬性。(但是,在K8S v1.18.0以后,–replicas已棄用 ,推薦用 kubectl apply 創建 pods)
- 方式二
通過配置文件和kubectl apply創建。
步驟:
1.編寫yml配置文件。(下一頁有書寫樣例,nginx.yml)
2.執行命令:kubectl apply -f /home/muse/nginx.yml
nginx.yml配置文件
- replicas: 2
部署的副本實例數量,默認為1
- metadata:
metadata定義Pod的元數據,至少要定義一個 label。label的key和value可以任意指定
- spec:
描述Pod的規格,此部分定義Pod中每一個容 器的屬性,name和image是必需的
構建過程解析
用戶通過kubectl——>創建Deployment——>創建ReplicaSet——>創建Pod
Failover
設置了pod數為3個
當Node1異常的時候,會在Node2上面生成新的Pod來維護總數為3個pod
當Node1恢復正常的時候,新創建的pod也依然會在Node2上,並不會做遷移動作。
label
默認配置下,Scheduler會將Pod調度到所有可用的Node。不過有些情況我們可以通過lable將Pod部署到指定的Node,比如將有大量磁盤I/O的Pod部署到配置了SSD的 Node;或者Pod需要GPU,需要運行在配置了GPU的節點上。
- 給k8s-node1添加標簽——disktype=ssd
kubectl label node k8s-node1disktype=ssd
- 修改nginx.yml配置文件,指定nodeSelector為上一步新建的label。
nodeSelector:
disktype: ssd
- 重新部署Deployment
kubectl apply -f nginx.yml
- 查看節點的標簽信息
kubectl get node --show-labels
[root@zhaowa-edu-01 k8sConfigFiles]# kubectl get node
NAME STATUS ROLES AGE VERSION
zhaowa-edu-01 Ready control-plane,master 22h v1.20.2
[root@zhaowa-edu-01 k8sConfigFiles]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
zhaowa-edu-01 Ready control-plane,master 22h v1.20.2
beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kube
rnetes.io/hostname=zhaowa-edu-
01,kubernetes.io/os=linux,minikube.k8s.io/commit=b017ea15ffbf8bcd6ce31e13ba16f59fd40910
79,minikube.k8s.io/name=minikube,minikube.k8s.io/updated_at=2021_09_18T13_04_08_0700,mi
nikube.k8s.io/version=v1.20.0,node-role.kubernetes.io/control-plane=,noderole.kubernetes.io/master=
[root@zhaowa-edu-01 k8sConfigFiles]# kubectl label node zhaowa-edu-01 disktype=ssd
node/zhaowa-edu-01 labeled
[root@zhaowa-edu-01 k8sConfigFiles]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
zhaowa-edu-01 Ready control-plane,master 22h v1.20.2
beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/ar
ch=amd64,kubernetes.io/hostname=zhaowa-edu-
01,kubernetes.io/os=linux,minikube.k8s.io/commit=b017ea15ffbf8bcd6ce31e13ba16f59fd40910
79,minikube.k8s.io/name=minikube,minikube.k8s.io/updated_at=2021_09_18T13_04_08_0700,mi
nikube.k8s.io/version=v1.20.0,node-role.kubernetes.io/control-plane=,noderole.kubernetes.io/master=
[root@zhaowa-edu-01 k8sConfigFiles]# kubectl label node zhaowa-edu-01 disktypenode/zhaowa-edu-01 labeled
[root@zhaowa-edu-01 k8sConfigFiles]# kubectl get node --show-labels
NAME STATUS ROLES AGE VERSION LABELS
zhaowa-edu-01 Ready control-plane,master 22h v1.20.2
beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kube
rnetes.io/hostname=zhaowa-edu-
01,kubernetes.io/os=linux,minikube.k8s.io/commit=b017ea15ffbf8bcd6ce31e13ba16f59fd40910
79,minikube.k8s.io/name=minikube,minikube.k8s.io/updated_at=2021_09_18T13_04_08_0700,mi
nikube.k8s.io/version=v1.20.0,node-role.kubernetes.io/control-plane=,noderole.kubernetes.io/master=
刪除deployment
假設現在配置的是2個pod數。那么如果我們只是刪除其中的一個pod,依然會被deployment根據配置,再補充為2個pod。
-
當我們刪除掉deployment的時候,pod也會隨之自動被刪除。
-
刪除pod
kubectl delete pod nginx-deployment-7f4fc68488-5v4m7 -
刪除deployment
kubectl delete deployment nginx-deployment
-
DaemonSet
Deployment部署的副本pod會分布在各個Node上,每個Node都可能運行好幾個副本。
Daemonsetl的不同之處在於:每個Node上最多只能運行一個副本。
Daemon Set的典型應用場景
1.在每個節點上運行存儲 Daemon,比如 glusterd或 ceph
2.在每個節點上運行日志收集 Daemon,如 flunentdi或 logstashe
3.在毎個節點上運行監控 Daemon,比如 Prometheus Node Exporter或 collectd
查看k8s自己就用 Daemonsetie運行系統組件
Job
容器按照持續運行時間,可以分為服務類容器和工作類容器。
- 服務類容器通常持續提供服務,需 要一直運行,比如HTTP Server、Daemon等。
- 工作類容器則是一次性任務,比如批處理程序,完成后容器就退出。
Kubernetes的Deployment、ReplicaSet和DaemonSet都用於管理服務類容器;
對於工作類容器,我們使用Job。
Service
-
我們不應該期望Pod是健壯的,而是要假設Pod中的容器很可能因為各種原因發生故障而死掉。
-
Deployment等Controller會通過動態創建和銷毀Pod來保證應用整體的健壯性。換句話說,Pod是脆弱的,但應用是健壯的。
-
Service提供了固定的ip和端口,並且里面包含一組pod,即使Pod的ip發生變化,但是面對客戶端的是Service的固定ip和端口。
Rolling Update
滾動更新是一次只更新一小部分副本,成功后再更新更多的副本,最終完成所有副本的更新。滾動更新的最大好處是零停機,整個更新過程始終有副本在運行,從而保證了業務的連續性。
