Kubernetes 簡介及部署方法
Kubernetes(簡稱 K8s)是一個開源的容器編排平臺,用于自動化容器化應用的部署、擴展、管理和運維。它由 Google 基于內部的 Borg 系統經驗開發,2014 年開源后由云原生計算基金會(CNCF)維護,現已成為容器編排的事實標準。
一、K8s 的核心功能
K8s 的核心目標是解決容器化應用在大規模部署時的復雜性,主要功能包括:
p
- 自動化部署:支持通過配置文件定義應用部署規則,自動完成容器的創建、調度和啟動。
- 彈性伸縮:根據 CPU 使用率、內存占用等指標自動擴縮容(如 HPA Horizontal Pod Autoscaler),也支持手動調整副本數。
- 負載均衡:通過 Service 組件為 Pod(容器組)提供穩定的訪問地址,并自動實現流量分發。
- 自愈能力:當容器或節點故障時,自動重啟容器、替換故障節點上的 Pod,確保應用可用性。
- 滾動更新與回滾:支持應用版本的平滑更新(不中斷服務),若更新失敗可快速回滾到上一版本。
- 存儲編排:支持多種存儲類型(本地存儲、云存儲、分布式存儲等),可動態掛載到容器。
- 配置管理:通過 ConfigMap、Secret 等組件統一管理應用配置和敏感信息(如密碼、證書),避免硬編碼。
二、K8s 的核心組件
K8s 集群由控制平面(Control Plane)?和節點(Node)?兩部分組成,各組件協同工作實現集群管理。
1. 控制平面組件(集群的 “大腦”)
控制平面負責集群的全局決策(如調度、管理、監控),可部署在單個節點或多個節點(高可用架構)。
- API Server:所有操作的統一入口(通過 REST API 暴露),接收用戶輸入的命令,提供認證、授權、API注冊和發現等機制,是控制平面與其他組件、用戶的交互樞紐,負責認證、授權和請求處理。
- etcd:分布式鍵值數據庫,存儲集群的所有配置數據(如 Pod 狀態、部署規則等),是集群的 “數據源”。
- Scheduler:負責 Pod 的調度決策,根據節點資源(CPU、內存)、親和性規則、污點 / 容忍等條件,選擇最合適的節點運行 Pod。
- Controller Manager:運行各種控制器進程的組件,確保集群狀態與期望狀態一致。常見控制器包括:
- 節點控制器(Node Controller):監控節點故障并處理。
- 副本控制器(ReplicaSet Controller):確保 Pod 副本數符合期望。
- 部署控制器(Deployment Controller):管理 Deployment 的創建、更新和回滾。
- Cloud Controller Manager:可選組件,用于對接云服務提供商(如 AWS、阿里云)的 API,實現云資源(如負載均衡、存儲)的自動管理。
2. 節點組件(集群的 “工作單元”)
節點是實際運行容器的服務器(物理機或虛擬機),每個節點需安裝以下組件:
- kubelet:運行在每個節點上的代理程序,負責與控制平面通信,確保容器(按 Pod 定義)在節點上正常運行,并監控容器狀態。
- kube-proxy:運行在每個節點上的網絡代理,負責維護節點的網絡規則(如 Service 的負載均衡、Pod 間通信),實現集群內部和外部的網絡訪問。
- 容器運行時(Container Runtime):負責運行容器的軟件,K8s 支持 Docker、containerd、CRI-O 等符合容器運行時接口(CRI)的工具。
三、K8s 的核心概念
理解這些概念是使用 K8s 的基礎,它們是 K8s 抽象出的 “操作單元”。
概念 | 作用說明 |
Pod | 最小部署單元,由一個或多個緊密關聯的容器組成(共享網絡和存儲),是 K8s 調度的基本單位。 |
Service | 為 Pod 提供穩定的訪問地址(固定 IP 和端口),解決 Pod 動態創建 / 銷毀導致的地址變化問題,支持 ClusterIP(集群內訪問)、NodePort(節點端口)、LoadBalancer(負載均衡器)等類型。 |
Deployment | 用于管理無狀態應用的部署,支持滾動更新、回滾、擴縮容,通過控制 ReplicaSet 實現 Pod 的副本管理。 |
StatefulSet | 用于管理有狀態應用(如數據庫),為 Pod 提供穩定的名稱、網絡標識和存儲,確保部署順序和唯一性。 |
ConfigMap | 存儲非敏感配置信息(如環境變量、配置文件),可被 Pod 掛載為文件或環境變量,便于配置與代碼分離。 |
Secret | 存儲敏感信息(如密碼、Token),內容會被 Base64 編碼(非加密,需配合外部加密工具增強安全性),用法與 ConfigMap 類似。 |
Namespace | 用于集群內資源的隔離(如開發、測試、生產環境),避免資源命名沖突,可配合資源配額限制資源使用。 |
Label | 鍵值對標簽,用于對資源(Pod、Service 等)進行分類和篩選,是 K8s 中 “關聯資源” 的核心機制(如 Service 通過 Label 關聯 Pod)。 |
Ingress | 管理外部訪問集群內服務的規則(如 HTTP/HTTPS 路由),可實現域名轉發、SSL 終止等功能,需配合 Ingress Controller(如 Nginx Ingress)使用。 |
Volume | 為 Pod 提供持久化存儲,生命周期與 Pod 綁定(Pod 刪除后 Volume 可能保留,取決于存儲類型),支持 EmptyDir(臨時存儲)、HostPath(節點本地目錄)、PV/PVC(持久卷 / 持久卷聲明)等。 |
PV/PVC | PV(PersistentVolume)是集群級別的存儲資源(由管理員創建),PVC(PersistentVolumeClaim)是用戶對 PV 的 “申請”,實現存儲的 “按需分配”。 |
四、K8s 的工作流程(以部署應用為例)
- 用戶通過kubectl命令或 API 提交 Deployment 配置(定義應用鏡像、副本數等)。
- API Server 接收請求,驗證后將配置存入 etcd。
- Deployment Controller 檢測到 “期望狀態”(如 3 個副本)與 “當前狀態”(0 個副本)不一致,創建 ReplicaSet。
- ReplicaSet Controller 檢測到副本數不足,向 API Server 請求創建 Pod。
- Scheduler 根據節點資源和調度規則,為 Pod 選擇合適的節點。
- 目標節點的 kubelet 接收到 Pod 創建請求,通過容器運行時啟動容器。
- kube-proxy 更新節點網絡規則,確保 Service 能訪問到新創建的 Pod。
- 后續若 Pod 故障,kubelet 會重啟容器;若節點故障,Controller 會在其他節點重建 Pod,始終維持期望狀態。
五、K8s 的應用場景
- 微服務架構:適合部署由多個獨立服務組成的微服務應用,通過 Service 實現服務間通信,通過 Deployment/StatefulSet 管理不同類型的服務。
- CI/CD 集成:與 Jenkins、GitLab CI 等工具結合,實現代碼提交→構建鏡像→自動部署到 K8s 集群的全流程自動化。
- 多環境管理:通過 Namespace 隔離開發、測試、生產環境,使用 ConfigMap/Secret 區分不同環境的配置。
- 混合云 / 多云部署:K8s 的跨平臺特性支持在私有云、公有云(如 AWS EKS、阿里云 ACK)或混合環境中統一部署和管理應用。
六、K8s 的優勢與挑戰
- 優勢:
- 自動化程度高,減少人工運維成本;
- 彈性伸縮能力強,適應流量波動;
- 松耦合架構,支持應用快速迭代;
- 強大的生態系統(如監控、日志、服務網格工具)。
- 挑戰:
- 學習曲線陡峭,需掌握大量概念和操作;
- 集群運維復雜(如高可用配置、升級、故障排查);
- 網絡和存儲配置需結合具體場景設計;
- 資源開銷較高(控制平面和節點組件占用一定資源)。
七、K8s 生態系統
K8s 的強大得益于豐富的周邊工具,常見生態組件包括:
- 部署工具:Helm(K8s 包管理工具,簡化應用部署)、Kustomize(配置管理工具)。
- 監控與日志:Prometheus( metrics 監控)、Grafana(可視化)、ELK Stack(日志收集與分析)。
- 服務網格:Istio(流量管理、服務間通信加密、監控)。
- CI/CD:ArgoCD(GitOps 持續部署)、Tekton(云原生 CI/CD 管道)。
- 安全工具:Falco(運行時安全監控)、Trivy(容器鏡像漏洞掃描)。
總之,K8s 是容器化時代的核心技術之一,掌握它能有效提升大規模應用的管理效率和可靠性,但也需要結合實際場景合理規劃和使用。
K8S集群環境搭建
k8s中容器的管理方式
**centainerd**
默認情況下,K8S在創建集群時使用的方式
**docker**
Docker使用的普記錄最高,雖然K8S在1.24版本后已經費力了kubelet對docker的支持,但時可以借助cri-docker方式來實現集群創建
**cri-o**
CRI-O的方式是Kubernetes創建容器最直接的一種方式,在創建集群的時候,需要借助于cri-o插件的方式來實現Kubernetes集群的創建。
> [!NOTE]
>
> docker 和cri-o 這兩種方式要對kubelet程序的啟動參數進行設置
k8s 集群部署
k8s 環境部署說明
集群環境初始化
K8S中文官網:https://kubernetes.io/zh-cn/
| **主機名** ? ? ? ? ? ? ? ? ? | **ip** ? ? ? ? ? ? | **角色** ? ? ? ? ? ? ? ? ? ?|
| ---------------------------- | ------------------ | --------------------------- |
| ** harbor ** | **172.25.254.200** | **harbor倉庫** ? ? ? ? ? ? ?|
| ** master ** | **172.25.254.100** | **master,k8s集群控制節點** |
| ** node1 ** ?| **172.25.254.10** ?| **worker,k8s集群工作節點** |
| ** node2 ** ?| **172.25.254.20** ?| **worker,k8s集群工作節點** |
- 所有節點禁用selinux和防火墻
- 所有節點同步時間和解析
- 所有節點安裝docker-ce
- 所有節點禁用swap,注意注釋掉/etc/fstab文件中的定義
所有禁用swap和本地解析
]# systemctl mask swap.target
]# swapoff -a
]# vim /etc/fstab
?swap ? ?defaults ?? ?0 ?0????? 注釋這一行
[root@k8s-master ~]# vim /etc/hosts
```
所有安裝虛擬機docker
```bash
[root@k8s-master ~]# vim /etc/yum.repos.d/docker.repo
[docker]
name=docker
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable/
gpgcheck=0
[root@k8s-master ~]# dnf install docker-ce -y
```
搭建私有倉庫harbor
[root@k8s-master ~]# vim /etc/docker/daemon.json
{
? ? ? ? "registry-mirrors": ["https://reg.xie.org"],
}
[root@k8s-master ~]# ls -l /etc/docker/certs.d/reg.xie.org/ca.crt
[root@k8s-master ~]# systemctl enable --now docker
4.3.3 為Registry提加密傳輸
#生成認證key和證書
[root@docker ~]#? openssl req -newkey? rsa:4096 \-nodes -sha256 -keyout certs/xie.org.key \-addext "subjectAltName = DNS:reg.xie.org" \????? -x509 -days 365 -out certs/xie.org.crt
?#指定備用名稱
You are about to be asked to enter information that will be incorporated
?into your certificate request.
?What you are about to enter is what is called a Distinguished Name or a DN.
?There are quite a few fields but you can leave some blank
?For some fields there will be a default value,
?If you enter '.', the field will be left blank.----
Country Name (2 letter code) [XX]:CN
?State or Province Name (full name) []:Shaanxi
?Locality Name (eg, city) [Default City]:Xi'an
?Organization Name (eg, company) [Default Company Ltd]:xie
?Organizational Unit Name (eg, section) []:docker
?Common Name (eg, your name or your server's hostname) []:reg.xie.org
?Email Address []:admin@xie.org
?#啟動registry倉庫
[root@docker ~]# docker run -d -p 443:443 --restart=always --name registry \
?> --name registry -v /opt/registry:/var/lib/registry \
?> -v /root/certs:/certs \
?> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
?> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/xie.org.crt \
?> -e REGISTRY_HTTP_TLS_KEY=/certs/xie.org.key registry
測試:
[root@docker docker]# docker push reg.xie.org/busybox:latest?????
戶端沒有key和證書
Error response from daemon: Get "https://reg.xie.org/v2/": tls: failed to
verify certificate: x509: certificate signed by unknown authority
?#為客戶端建立證書
[root@docker docker]# mkdir /etc/docker/certs.d/reg.xie.org/ -p
?[root@docker docker]# cp /root/certs/xie.org.crt?
/etc/docker/certs.d/reg.xie.org/ca.crt
?[root@docker docker]# systemctl restart docker
?#docker客
[root@docker docker]# docker push reg.xie.org/busybox:latest??????????????
The push refers to repository [reg.xie.org/busybox]
?d51af96cf93e: Pushed
?latest: digest:
sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527
?[root@docker docker]# curl? -k https://reg.xie.org/v2/_catalog
?{"repositories":["busybox"]}
?4.3.4 為倉庫建立登陸認證
#安裝建立認證文件的工具包
[root@docker docker]# dnf install httpd-tools -y
?#建立認證文件
[root@docker ~]# mkdir auth
?[root@docker ~]# htpasswd -Bc auth/htpasswd xie?? #-B 強制使用最安全加密方式,
默認用md5加密
New password:
?Re-type new password:
?Adding password for user xie
?#添加認證到registry容器中??
[root@docker ~]# docker run -d -p 443:443 --restart=always --name registry \
?> --name registry -v /opt/registry:/var/lib/registry \
?> -v /root/certs:/certs \
?> -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
?> -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/xie.org.crt \
?> -e REGISTRY_HTTP_TLS_KEY=/certs/xie.org.key \
?> -v /root/auth:/auth \
?> -e "REGISTRY_AUTH=htpasswd" \
?> -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
?> -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
?> registry
?[root@docker ~]# curl -k https://reg.xie.org/v2/_catalog -u xie:lee
?{"repositories":["busybox","nginx"]}
?#登陸測試
[root@docker ~]# docker login reg.xie.org
?Username: xie
?Password:
?WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
?Configure a credential helper to remove this warning. See
?https://docs.docker.com/engine/reference/commandline/login/#credential-stores
?Login Succeeded
當倉庫開啟認證后必須登陸倉庫才能進行鏡像上傳
#未登陸情況下上傳鏡像
[root@docker ~]# docker push? reg.xie.org/busybox
?Using default tag: latest
?The push refers to repository [reg.xie.org/busybox]
?d51af96cf93e: Preparing
?no basic auth credentials
?#未登陸下不能下載
[root@docker-node2 ~]# docker pull reg.xie.org/busybox
?Using default tag: latest
?Error response from daemon: Head
"https://reg.xie.org/v2/busybox/manifests/latest": no basic auth
credentials
[root@docker ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
?[root@docker ~]# ls
?anaconda-ks.cfg? certs?? harbor-offline-installer-v2.5.4.tgz
?auth????????????
harbor
?[root@docker ~]# cd harbor/
?[root@docker harbor]# cp harbor.yml.tmpl harbor.yml
?[root@docker harbor]# vim harbor.yml
hostname: reg.xie.org
?certificate: /data/certs/xie.org.crt
?private_key: /data/certs/xie.org.key
?harbor_admin_password: lee
?[root@docker harbor]# ./install.sh --help
?Please set --with-notary???????????????
Please set --with-trivy????????????????
#證書簽名
#安全掃描
Please set --with-chartmuseum if needs enable Chartmuseum in Harbor
?[root@docker harbor]# ./install.sh --with-chartmuseum
?#管理harbor的容器
[root@docker harbor]# docker compose stop
[root@docker harbor]# docker compose? up -d
輸入用戶名和密碼后
docker info
認證harbor倉庫 https://reg.xie.org
####? 安裝K8S部署工具
```bash
#部署軟件倉庫,添加K8S源
[root@k8s-master ~]# vim /etc/yum.repos.d/k8s.repo
[k8s]
name=k8s
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm
gpgcheck=0
#安裝軟件
[root@k8s-master ~]# dnf install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y
```
####? 設置kubectl命令補齊功能
```
[root@k8s-master ~]# dnf install bash-completion -y
[root@k8s-master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@k8s-master ~]# source ?~/.bashrc
在所節點安裝cri-docker
k8s從1.24版本開始移除了dockershim,所以需要安裝cri-docker插件才能使用docker
軟件下載:https://github.com/Mirantis/cri-dockerd
```bash
[root@k8s-master ~]# dnf install libcgroup-0.41-19.el8.x86_64.rpm \
> cri-dockerd-0.3.14-3.el8.x86_64.rpm -y
[root@k8s-master ~]# vim /lib/systemd/system/cri-docker.service
[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl start cri-docker
cri-dockerd的套接字文件
在master節點拉取K8S所需鏡像
#拉取k8s集群所需要的鏡像
[root@k8s-master ~]# kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
#上傳鏡像到harbor倉庫
[root@k8s-master ~]# docker images | awk '/google/{ print $1":"$2}' \
| awk -F "/" '{system("docker tag "$0" reg.xie.org/k8s/"$3)}'
[root@k8s-master ~]# docker images ?| awk '/k8s/{system("docker push "$1":"$2)}' ? ? ? ?
```
集群初始化
```bash
#啟動kubelet服務
[root@k8s-master ~]# systemctl status kubelet.service
#執行初始化命令
[root@k8s-master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 \
--image-repository reg.xie.org/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
#指定集群配置文件變量
[root@k8s-master~]#echo"export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
#當前節點沒有就緒,因為還沒有安裝網絡插件,容器沒有運行
[root@k8s-master ~]# kubectl get node
NAME ? ? ? ? ? ? ? ? ? ? ? STATUS ? ? ROLES ? ? ? ? ? AGE ? ? VERSION
k8s-master.xie.org ? NotReady ? control-plane ? 4m25s ? v1.30.0
root@k8s-master ~]# kubectl get pod -A
NAMESPACE ? ? NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? READY ? STATUS ? ?RESTARTS ? AGE
kube-system??? coredns-647dc958972sgn8? ?0/1 ? ?Pending ??0 ????6m13s
kube-system ?coredns-647dc95897-bvtxb ? 0/1 ? ? Pending ? 0 ??6m13s
kube-system ? etcd-k8s-master.xie.org 1/1 ? ? Running ?? 0 ??6m29s
kube-system??? kube-apiserver-k8s-master.xie.org 1/1 Running 0 6m30s
kube-system kube-controller-manager-k8s-master.xie.org1/1 Running 0? 6m29s
kube-system ?kube-proxy-fq85m ? ?? 1/1 ? ? Running ? 0?6m14s
kube-system ? kube-scheduler-k8s-master.xie.org 1/1 Running ?0 6m29s
```
> [!NOTE]
>
> 在此階段如果生成的集群token找不到了可以重新生成
>
> ```bash
> [root@k8s-master ~]# ? kubeadm token create --print-join-command
kubeadm join 172.25.254.100:6443 --token slx36w.np3pg2xzfhtj8hsr \
? ? ? ? --discovery-token-ca-cert-hash sha256:29389ead6392e0bb1f68adb025e3a6817c9936a26f9140f8a166528e521addb3 --cri-socket=unix:///var/run/cri-dockerd.sock
kubeadm join 172.25.254.100:6443 --token olyuv1.g1q8jht9b1p69xla --discovery-token-ca-cert-hash sha256:29389ead6392e0bb1f68adb025e3a6817c9936a26f9140f8a166528e521addb3 --cri-socket=unix:///var/run/cri-dockerd.sock
> ```
#### 2.2.2.10 安裝flannel網絡插件
官方網站:https://github.com/flannel-io/flannel
```bash
#下載flannel的yaml部署文件
[root@k8s-master ~]# wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
#下載鏡像:
[root@k8s-master ~]# docker pull docker.io/flannel/flannel:v0.25.5
[root@k8s-master ~]# docekr docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1
#上傳鏡像到倉庫
[root@k8s-master ~]# docker tag flannel/flannel:v0.25.5 \
reg.xie.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker push reg.xie.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1 \
reg.xie.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
[root@k8s-master ~]# docker push reg.xie.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
#編輯kube-flannel.yml 修改鏡像下載位置
[root@k8s-master ~]# vim kube-flannel.yml
#需要修改以下幾行
[root@k8s-master ~]# grep -n image kube-flannel.yml
146: ? ? ? ?image: reg.xie.org/flannel/flannel:v0.25.5
173: ? ? ? ?image: reg.xie.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
184: ? ? ? ?image: reg.xie.org/flannel/flannel:v0.25.5
#安裝flannel網絡插件
[root@k8s-master ~]# kubectl apply -f kube-flannel.yml
```
#### 2.2.2.11 節點擴容
在所有的worker節點中
1 確認部署好以下內容
2 禁用swap
3 安裝:
- kubelet-1.30.0
- kubeadm-1.30.0
- kubectl-1.30.0
- docker-ce
- ?cri-dockerd
4 修改cri-dockerd啟動文件添加
- --network-plugin=cni
- ?--pod-infra-container-image=reg.xie.org/k8s/pause:3.9
5 啟動服務
- kubelet.service
- cri-docker.service
?以上信息確認完畢后即可加入集群
```
[root@k8s-node1 & 2 ?~]# kubeadm join 172.25.254.100:6443 --token 5hwptm.zwn7epa6pvatbpwf --discovery-token-ca-cert-hash sha256:52f1a83b70ffc8744db5570288ab51987ef2b563bf906ba4244a300f61e9db23 --cri-socket=unix:///var/run/cri-dockerd.sock
在master階段中查看所有node的狀態
```
[root@k8s-master ~]# kubectl get nodes
測試集群運行情況
```
#建立一個pod
[root@k8s-master ~]# kubectl run test --image nginx
#查看pod狀態
[root@k8s-master ~]# kubectl get pods
Kubernetes中pod的管理及優化
資源管理介紹
- 在kubernetes中,所有的內容都抽象為資源,用戶需要通過操作資源來管理kubernetes。
- kubernetes的本質上就是一個集群系統,用戶可以在集群中部署各種服務
- 所謂的部署服務,其實就是在kubernetes集群中運行一個個的容器,并將指定的程序跑在容器中。
- kubernetes的最小管理單元是pod而不是容器,只能將容器放在`Pod`中,
- kubernetes一般也不會直接管理Pod,而是通過`Pod控制器`來管理Pod的。
- Pod中服務的訪問是由kubernetes提供的`Service`資源來實現。
- Pod中程序的數據需要持久化是由kubernetes提供的各種存儲系統來實現
資源管理方式
- 命令式對象管理:直接使用命令去操作kubernetes資源
? `kubectl run nginx-pod --image=nginx:latest --port=80`
- 命令式對象配置:通過命令配置和配置文件去操作kubernetes資源
? `kubectl create/patch -f nginx-pod.yaml`
- 聲明式對象配置:通過apply命令和配置文件去操作kubernetes資源
? `kubectl apply -f nginx-pod.yaml`
| 類型?????????? |適用環境|??? 優點 ? ??|???????? 缺點 ? ? ?|
| 命令式對象管理 | 測試 ? ? | 簡單 | 只能操作活動對象,無法審計、跟蹤
| 命令式對象配置 | 開發 ? ? | 可以審計、跟蹤 | 項目大時,配置文件多,操作麻煩 ? |
| 聲明式對象配置 | 開發 ? ? | 支持目錄操作 ? | 意外情況下難以調試 ?
命令式對象管理
kubectl是kubernetes集群的命令行工具,通過它能夠對集群本身進行管理,并能夠在集群上進行容器化應用的安裝部署
kubectl命令的語法如下:
```
kubectl [command] [type] [name] [flags]
```
**comand**:指定要對資源執行的操作,例如create、get、delete
**type**:指定資源類型,比如deployment、pod、service
**name**:指定資源的名稱,名稱大小寫敏感
**flags**:指定額外的可選參數
```
# 查看所有pod
kubectl get pod
# 查看某個pod
kubectl get pod pod_name
# 查看某個pod,以yaml格式展示結果
kubectl get pod pod_name -o yaml
資源類型
kubernetes中所有的內容都抽象為資源
基本命令示例
kubectl version
kubectl? cluster-info
#創建一個webcluster控制器,控制器中pod數量為2
kubectl create deployment webcluseter --image nginx --replicas 2
#查看控制器
[root@k8s-master ~]# kubectl get ?deployments.apps
#查看資源幫助
[root@k8s-master ~]# kubectl explain deployment
#查看控制器參數幫助
[root@k8s-master ~]# kubectl explain deployment.spec
#編輯控制器配置
[root@k8s-master ~]# kubectl edit deployments.apps webcluseter
#刪除資源
[root@k8s-master ~]# kubectl delete deployments.apps webcluseter
deployment.apps " webcluseter" deleted
[root@k8s-master ~]# kubectl get deployments.apps
運行和調試命令示例
#端口暴漏
[root@k8s-master ~]# kubectl get ?services
[root@k8s-master ~]# kubectl expose pod testpod --port 80 --target-port 80
[root@k8s-master ~]# kubectl get services
[root@k8s-master ~]# curl 10.110.169.130
#查看資源日志
[root@k8s-master ~]# kubectl logs pods/testpod
#利用命令生成yaml模板文件
[root@k8s-master ~]# kubectl create deployment --image nginx webcluster --dry-run=client ? -o yaml ?> webcluster.yml
#利用yaml文件生成資源
[root@k8s-master ~]# vim webcluster.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? creationTimestamp: null
? labels:
? ? app: webcluster
? name: webcluster
spec:
? replicas: 2
? selector:
? ? matchLabels:
? ? ? app: webcluster
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: webcluster
? ? spec:
? ? ? containers:
? ? ? - image: nginx
? ? ? ? name: nginx
[root@k8s-master ~]# kubectl apply -f webcluster.yml
[root@k8s-master ~]# kubectl get deployments.apps
[root@k8s-master ~]# kubectl delete -f webcluster.yml
利用控制器管理pod(推薦)
**高可用性和可靠性**:
- **自動故障恢復**:如果一個 Pod 失敗或被刪除,控制器會自動創建新的 Pod 來維持期望的副本數量。確保應用始終處于可用狀態,減少因單個 Pod 故障導致的服務中斷。
- **健康檢查和自愈**:可以配置控制器對 Pod 進行健康檢查(如存活探針和就緒探針)。如果 Pod 不健康,控制器會采取適當的行動,如重啟 Pod 或刪除并重新創建它,以保證應用的正常運行。
**可擴展性**:
- **輕松擴縮容**:可以通過簡單的命令或配置更改來增加或減少 Pod 的數量,以滿足不同的工作負載需求。例如,在高流量期間可以快速擴展以處理更多請求,在低流量期間可以縮容以節省資源。
- **水平自動擴縮容(HPA)**:可以基于自定義指標(如 CPU 利用率、內存使用情況或應用特定的指標)自動調整 Pod 的數量,實現動態的資源分配和成本優化。
**版本管理和更新**:
- **滾動更新**:對于 Deployment 等控制器,可以執行滾動更新來逐步替換舊版本的 Pod 為新版本,確保應用在更新過程中始終保持可用。可以控制更新的速率和策略,以減少對用戶的影響。
- **回滾**:如果更新出現問題,可以輕松回滾到上一個穩定版本,保證應用的穩定性和可靠性。
**聲明式配置**:
- **簡潔的配置方式**:使用 YAML 或 JSON 格式的聲明式配置文件來定義應用的部署需求。這種方式使得配置易于理解、維護和版本控制,同時也方便團隊協作。
- **期望狀態管理**:只需要定義應用的期望狀態(如副本數量、容器鏡像等),控制器會自動調整實際狀態與期望狀態保持一致。無需手動管理每個 Pod 的創建和刪除,提高了管理效率。
**服務發現和負載均衡**:
- **自動注冊和發現**:Kubernetes 中的服務(Service)可以自動發現由控制器管理的 Pod,并將流量路由到它們。這使得應用的服務發現和負載均衡變得簡單和可靠,無需手動配置負載均衡器。
- **流量分發**:可以根據不同的策略(如輪詢、隨機等)將請求分發到不同的 Pod,提高應用的性能和可用性。
**多環境一致性**:
- **一致的部署方式**:在不同的環境(如開發、測試、生產)中,可以使用相同的控制器和配置來部署應用,確保應用在不同環境中的行為一致。這有助于減少部署差異和錯誤,提高開發和運維效率。
#建立控制器并自動運行pod
[root@k8s-master ~]# kubectl create deployment xie --image nginx
[root@k8s-master ~]# kubectl get pods
[root@k8s-master ~]# kubectl scale deployment xie --replicas 6
#為xie縮容
root@k8s-master ~]# kubectl scale deployment xie --replicas 2
deployment.apps/xie scaled
[root@k8s-master ~]# kubectl get pods
應用版本的更新
```bash
#利用控制器建立pod
[root@k8s-master ~]# kubectl create ?deployment xie --image myapp:v1 --replicas 2
#暴漏端口
[root@k8s-master ~]# kubectl expose deployment xie --port 80 --target-port 80
[root@k8s-master ~]# kubectl get services
#產看歷史版本
[root@k8s-master ~]# kubectl rollout history deployment xie
#更新控制器鏡像版本
[root@k8s-master ~]# kubectl set image deployments/xie myapp=myapp:v2
#查看歷史版本
[root@k8s-master ~]# kubectl rollout history deployment xie
#訪問內容測試
[root@k8s-master ~]# curl 10.98.134.63
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
#版本回滾
[root@k8s-master ~]# kubectl rollout undo deployment xie --to-revision 1
deployment.apps/xie rolled back
[root@k8s-master ~]# curl ?10.98.134.63
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
利用yaml文件部署應用
###? 用yaml文件部署應用有以下優點
**聲明式配置**:
- 清晰表達期望狀態:以聲明式的方式描述應用的部署需求,包括副本數量、容器配置、網絡設置等。這使得配置易于理解和維護,并且可以方便地查看應用的預期狀態。
- 可重復性和版本控制:配置文件可以被版本控制,確保在不同環境中的部署一致性。可以輕松回滾到以前的版本或在不同環境中重復使用相同的配置。
- 團隊協作:便于團隊成員之間共享和協作,大家可以對配置文件進行審查和修改,提高部署的可靠性和穩定性。
**靈活性和可擴展性**:
- 豐富的配置選項:可以通過 YAML 文件詳細地配置各種 Kubernetes 資源,如 Deployment、Service、ConfigMap、Secret 等。可以根據應用的特定需求進行高度定制化。
- 組合和擴展:可以將多個資源的配置組合在一個或多個 YAML 文件中,實現復雜的應用部署架構。同時,可以輕松地添加新的資源或修改現有資源以滿足不斷變化的需求。
**與工具集成**:
- 與 CI/CD 流程集成:可以將 YAML 配置文件與持續集成和持續部署(CI/CD)工具集成,實現自動化的應用部署。例如,可以在代碼提交后自動觸發部署流程,使用配置文件來部署應用到不同的環境。
- 命令行工具支持:Kubernetes 的命令行工具 `kubectl` 對 YAML 配置文件有很好的支持,可以方便地應用、更新和刪除配置。同時,還可以使用其他工具來驗證和分析 YAML 配置文件,確保其正確性和安全性。
###? 資源清單參數
| 參數名稱 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| 類型 ? ?| 參數說明 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| ------------------------------------------- | ------- | ------------------------------------------------------------ |
| version ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | String ?| 這里是指的是K8S API的版本,目前基本上是v1,可以用kubectl api-versions命令查詢 |
| kind ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| String ?| 這里指的是yaml文件定義的資源類型和角色,比如:Pod ? ? ? ? ? ? |
| metadata ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Object ?| 元數據對象,固定值就寫metadata ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| metadata.name ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | String ?| 元數據對象的名字,這里由我們編寫,比如命名Pod的名字 ? ? ? ? ?|
| metadata.namespace ? ? ? ? ? ? ? ? ? ? ? ? ?| String ?| 元數據對象的命名空間,由我們自身定義 ? ? ? ? ? ? ? ? ? ? ? ? |
| Spec ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Object ?| 詳細定義對象,固定值就寫Spec ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[] ? ? ? ? ? ? ? ? ? ? ? ? ? | list ? ?| 這里是Spec對象的容器列表定義,是個列表 ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].name ? ? ? ? ? ? ? ? ? ? ?| String ?| 這里定義容器的名字 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].image ? ? ? ? ? ? ? ? ? ? | string ?| 這里定義要用到的鏡像名稱 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].imagePullPolicy ? ? ? ? ? | String ?| 定義鏡像拉取策略,有三個值可選: ? ? ? ? (1) Always: 每次都嘗試重新拉取鏡像 ? ? ? ? (2) IfNotPresent:如果本地有鏡像就使用本地鏡像 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (3) )Never:表示僅使用本地鏡像 |
| spec.containers[].command[] ? ? ? ? ? ? ? ? | list ? ?| 指定容器運行時啟動的命令,若未指定則運行容器打包時指定的命令 |
| spec.containers[].args[] ? ? ? ? ? ? ? ? ? ?| list ? ?| 指定容器運行參數,可以指定多個 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].workingDir ? ? ? ? ? ? ? ?| String ?| 指定容器工作目錄 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].volumeMounts[] ? ? ? ? ? ?| list ? ?| 指定容器內部的存儲卷配置 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].volumeMounts[].name ? ? ? | String ?| 指定可以被容器掛載的存儲卷的名稱 ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].volumeMounts[].mountPath ?| String ?| 指定可以被容器掛載的存儲卷的路徑 ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].volumeMounts[].readOnly ? | String ?| 設置存儲卷路徑的讀寫模式,ture或false,默認為讀寫模式 ? ? ? ?|
| spec.containers[].ports[] ? ? ? ? ? ? ? ? ? | list ? ?| 指定容器需要用到的端口列表 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].ports[].name ? ? ? ? ? ? ?| String ?| 指定端口名稱 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].ports[].containerPort ? ? | String ?| 指定容器需要監聽的端口號 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[] ports[].hostPort ? ? ? ? ?| String ?| 指定容器所在主機需要監聽的端口號,默認跟上面containerPort相同,注意設置了hostPort同一臺主機無法啟動該容器的相同副本(因為主機的端口號不能相同,這樣會沖突) |
| spec.containers[].ports[].protocol ? ? ? ? ?| String ?| 指定端口協議,支持TCP和UDP,默認值為 ?TCP ? ? ? ? ? ? ? ? ? ?|
| spec.containers[].env[] ? ? ? ? ? ? ? ? ? ? | list ? ?| 指定容器運行前需設置的環境變量列表 ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].env[].name ? ? ? ? ? ? ? ?| String ?| 指定環境變量名稱 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].env[].value ? ? ? ? ? ? ? | String ?| 指定環境變量值 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].resources ? ? ? ? ? ? ? ? | Object ?| 指定資源限制和資源請求的值(這里開始就是設置容器的資源上限) ? |
| spec.containers[].resources.limits ? ? ? ? ?| Object ?| 指定設置容器運行時資源的運行上限 ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].resources.limits.cpu ? ? ?| String ?| 指定CPU的限制,單位為核心數,1=1000m ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].resources.limits.memory ? | String ?| 指定MEM內存的限制,單位為MIB、GiB ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
| spec.containers[].resources.requests ? ? ? ?| Object ?| 指定容器啟動和調度時的限制設置 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| spec.containers[].resources.requests.cpu ? ?| String ?| CPU請求,單位為core數,容器啟動時初始化可用數量 ? ? ? ? ? ? ?|
| spec.containers[].resources.requests.memory | String ?| 內存請求,單位為MIB、GIB,容器啟動的初始化可用數量 ? ? ? ? ? |
| spec.restartPolicy ? ? ? ? ? ? ? ? ? ? ? ? ?| string ?| 定義Pod的重啟策略,默認值為Always. ?(1)Always: Pod-旦終止運行,無論容器是如何 ?終止的,kubelet服務都將重啟它 ?(2)OnFailure: 只有Pod以非零退出碼終止時,kubelet才會重啟該容器。如果容器正常結束(退出碼為0),則kubelet將不會重啟它 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (3) Never: Pod終止后,kubelet將退出碼報告給Master,不會重啟該 |
| spec.nodeSelector ? ? ? ? ? ? ? ? ? ? ? ? ? | Object ?| 定義Node的Label過濾標簽,以key:value格式指定 ? ? ? ? ? ? ? ? |
| spec.imagePullSecrets ? ? ? ? ? ? ? ? ? ? ? | Object ?| 定義pull鏡像時使用secret名稱,以name:secretkey格式指定 ? ? ? |
| spec.hostNetwork ? ? ? ? ? ? ? ? ? ? ? ? ? ?| Boolean | 定義是否使用主機網絡模式,默認值為false。設置true表示使用宿主機網絡,不使用docker網橋,同時設置了true將無法在同一臺宿主機 ?上啟動第二個副本 |
###? 如何獲得資源幫助
```
kubectl explain pod.spec.containers
```
###? 編寫示例
運行多個容器pod
> [!WARNING]
>
> 注意如果多個容器運行在一個pod中,資源共享的同時在使用相同資源時也會干擾,比如端口
```bash
#一個端口干擾示例:
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: timing
? name: xie
spec:
? containers:
? ? - image: ?nginx:latest
? ? ? name: web1
? ? - image: nginx:latest
? ? ? name: web2
? ? ?
[root@k8s-master ~]# kubectl apply -f pod.yml
[root@k8s-master ~]# kubectl get pods
> [!NOTE]
>
> 在一個pod中開啟多個容器時一定要確保容器彼此不能互相干擾
端口映射
```bash
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: xie
? name: test
spec:
? containers:
? ? - image: myapp:v1
? ? ? name: myapp1
? ? ? ports:
? ? ? - name: http
? ? ? ? containerPort: 80
? ? ? ? hostPort: 80
? ? ? ? protocol: TCP
#測試
[root@k8s-master ~]# kubectl apply -f pod.yml
[root@k8s-master ~]# kubectl get pods ?-o wide
如何設定環境變量
```bash
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: xie
? name: test
spec:
? containers:
? ? - image: busybox:latest
? ? ? name: busybox
? ? ? command: ["/bin/sh","-c","echo $NAME;sleep 3000000"]
? ? ? env:
? ? ? - name: NAME
? ? ? ? value: xie
[root@k8s-master ~]# kubectl apply -f pod.yml
選擇運行節點
```
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: xie
? name: test
spec:
? nodeSelector:
? ? kubernetes.io/hostname: node1
? restartPolicy: Always
? containers:
? ? - image: myapp:v1
? ? ? name: myapp
[root@k8s-master ~]# kubectl apply -f pod.yml
[root@k8s-master ~]# kubectl get pods ?-o wide
探針
**探針是由 kubelet 對容器執行的定期診斷:**
- ExecAction:在容器內執行指定命令。如果命令退出時返回碼為 0 則認為診斷成功。
- TCPSocketAction:對指定端口上的容器的 IP 地址進行 TCP 檢查。如果端口打開,則診斷被認為是成功的。
- HTTPGetAction:對指定的端口和路徑上的容器的 IP 地址執行 HTTP Get 請求。如果響應的狀態碼大于等于200 且小于 400,則診斷被認為是成功的。
每次探測都將獲得以下三種結果之一:
- 成功:容器通過了診斷。
- 失敗:容器未通過診斷。
- 未知:診斷失敗,因此不會采取任何行動。
**Kubelet 可以選擇是否執行在容器上運行的三種探針執行和做出反應:**
- livenessProbe:指示容器是否正在運行。如果存活探測失敗,則 kubelet 會殺死容器,并且容器將受到其重啟策略的影響。如果容器不提供存活探針,則默認狀態為 Success。
- readinessProbe:指示容器是否準備好服務請求。如果就緒探測失敗,端點控制器將從與 Pod 匹配的所有 Service 的端點中刪除該 Pod 的 IP 地址。初始延遲之前的就緒狀態默認為 Failure。如果容器不提供就緒探針,則默認狀態為 Success。
- startupProbe: 指示容器中的應用是否已經啟動。如果提供了啟動探測(startup probe),則禁用所有其他探測,直到它成功為止。如果啟動探測失敗,kubelet 將殺死容器,容器服從其重啟策略進行重啟。如果容器沒有提供啟動探測,則默認狀態為成功Success。
**ReadinessProbe 與 LivenessProbe 的區別**
- ReadinessProbe 當檢測失敗后,將 Pod 的 IP:Port 從對應的 EndPoint 列表中刪除。
- LivenessProbe 當檢測失敗后,將殺死容器并根據 Pod 的重啟策略來決定作出對應的措施
**StartupProbe 與 ReadinessProbe、LivenessProbe 的區別**
- 如果三個探針同時存在,先執行 StartupProbe 探針,其他兩個探針將會被暫時禁用,直到 pod 滿足 StartupProbe 探針配置的條件,其他 2 個探針啟動,如果不滿足按照規則重啟容器。
- 另外兩種探針在容器啟動后,會按照配置,直到容器消亡才停止探測,而 StartupProbe 探針只是在容器啟動后按照配置滿足一次后,不在進行后續的探測。
k8s中的控制器應用
什么是控制器
控制器也是管理pod的一種手段
- 自主式pod:pod退出或意外關閉后不會被重新創建
- 控制器管理的 Pod:在控制器的生命周期里,始終要維持 Pod 的副本數目
Pod控制器是管理pod的中間層,使用Pod控制器之后,只需要告訴Pod控制器,想要多少個什么樣的Pod就可以了,它會創建出滿足條件的Pod并確保每一個Pod資源處于用戶期望的目標狀態。如果Pod資源在運行中出現故障,它會基于指定策略重新編排
當建立控制器后,會把期望值寫入etcd,k8s中的apiserver檢索etcd中我們保存的期望狀態,并對比pod的當前狀態,如果出現差異代碼自驅動立即恢復
?控制器常用類型
控制器類型 | 核心用途 | 關鍵特性 | 典型適用場景 |
Deployment(部署) | 管理無狀態應用的部署、更新和自愈 | 1. 維護指定數量的 Pod 副本 | 無狀態服務(如 Web 應用、API 服務、前端服務) |
StatefulSet(有狀態集) | 管理有狀態應用,提供穩定標識和持久化存儲 | 1. 固定 Pod 名稱和 DNS 標識(如web-0、web-1) | 有狀態服務(如數據庫 MySQL、分布式系統 ZooKeeper、消息隊列 Kafka) |
DaemonSet(守護進程集) | 確保所有(或指定)節點運行相同的 Pod | 1. 新節點加入時自動部署 Pod | 集群級支撐服務(如日志收集 Fluentd、監控代理 Node Exporter、網絡插件 Calico) |
ReplicaSet(副本集) | 維持指定數量的 Pod 副本(Deployment 的底層組件) | 1. 通過標簽選擇器管理 Pod | 通常不直接使用,由 Deployment 間接管理 |
Job(任務) | 管理一次性任務,確保任務成功完成 | 1. 任務完成后終止(退出碼為 0) | 批處理任務(如數據備份、日志分析、數據庫遷移) |
CronJob(定時任務) | 基于時間調度周期性執行任務(類似 crontab) | 1. 支持 cron 表達式定義執行時間 | 定時任務(如日志清理、數據同步、周期性報表生成) |
HorizontalPodAutoscaler(HPA) | 根據指標自動調整 Pod 副本數量(水平擴縮容) | 1. 基于 CPU / 內存或自定義指標觸發擴縮容 | 流量波動大的服務(如電商促銷期擴容、低谷期縮容) |
replicaset控制器
replicaset功能
- ReplicaSet 是下一代的 Replication Controller,官方推薦使用ReplicaSet
- ReplicaSet和Replication Controller的唯一區別是選擇器的支持,ReplicaSet支持新的基于集合的選擇器需求
- ReplicaSet 確保任何時間都有指定數量的 Pod 副本在運行
- 雖然 ReplicaSets 可以獨立使用,但今天它主要被Deployments 用作協調 Pod 創建、刪除和更新的機制
配置層級 | 參數名稱 | 核心作用 | 取值說明 / 約束 | 是否必填 |
頂層元數據 | apiVersion | 定義 ReplicaSet 使用的 Kubernetes API 版本 | 固定為?apps/v1(K8s 1.9+ 版本統一,舊版本?extensions/v1beta1?已廢棄) | 是 |
kind | 聲明資源類型為 ReplicaSet | 固定為?ReplicaSet | 是 | |
metadata | 定義 ReplicaSet 自身的元數據 | 包含?name(資源名)、namespace(所屬命名空間,默認?default)、labels(標簽)等 | 是(至少含?name) | |
核心期望狀態 | spec.replicas | 指定需要維持的 Pod 副本數量 | 非負整數,默認值為?1;設為?0?可刪除所有受控 Pod | 否(有默認值) |
spec.selector | 定義標簽選擇器,用于匹配 / 管理 Pod | 僅支持?matchLabels(精確匹配標簽),需與?spec.template.metadata.labels?完全一致 | 是 | |
spec.selector.matchLabels | 鍵值對形式的標簽匹配規則,篩選出 ReplicaSet 要管理的 Pod | 例:app: nginx(僅匹配標簽?app=nginx?的 Pod) | 是(嵌套在?selector?下) | |
Pod 模板 | spec.template | 定義用于創建 Pod 的模板(PodTemplate),所有受控 Pod 均基于此模板生成 | 需符合 Pod 配置規范,包含?metadata(Pod 標簽)和?spec(Pod 容器等配置) | 是 |
spec.template.metadata | 定義 Pod 的元數據,核心是?Pod 標簽 | 標簽需與?spec.selector.matchLabels?匹配,否則 ReplicaSet 無法管理生成的 Pod | 是(至少含匹配標簽) | |
spec.template.spec | 定義 Pod 的具體配置,如容器、存儲、網絡等 | 包含?containers(容器列表,必填)、volumes(存儲卷)、restartPolicy(重啟策略)等 | 是(至少含?containers) | |
Pod 模板 - 容器 | spec.template.spec.containers | 定義 Pod 中的容器列表,每個容器需配置核心參數 | 數組形式,至少包含 1 個容器 | 是(嵌套在?template.spec?下) |
containers[].name | 定義容器名稱(Pod 內唯一) | 字符串,需符合 DNS 子域名規范(如?nginx-container) | 是(每個容器必填) | |
containers[].image | 指定容器使用的鏡像(如鏡像倉庫地址、版本標簽) | 例:nginx:1.25(指定 Nginx 1.25 版本);若未指定標簽,默認拉取?latest?版本 | 是(每個容器必填) | |
Pod 模板 - 重啟策略 | spec.template.spec.restartPolicy | 定義 Pod 內容器故障時的重啟策略,影響 ReplicaSet 自愈邏輯 | 可選值: | 否(默認?Always) |
replicaset 示例
```bash
#生成yml文件
[root@k8s-master ~]# kubectl create deployment replicaset --image myapp:v1 --dry-run=client -o yaml > replicaset.yml
[root@k8s-master ~]# vim replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
? name: replicaset ? ?#指定pod名稱,一定小寫,如果出現大寫報錯
spec:
? replicas: 2 ? ? #指定維護pod數量為2
? selector: ? ? ? #指定檢測匹配方式
? ? matchLabels: ? ?#指定匹配方式為匹配標簽
? ? ? app: myapp ? ?#指定匹配的標簽為app=myapp
? template: ? ? ? #模板,當副本數量不足時,會根據下面的模板創建pod副本
? ? metadata:
? ? ? labels:
? ? ? ? app: myapp
? ? spec:
? ? ? containers:
? ? ? - image: myapp:v1
? ? ? ? name: myapp
[root@k8s-master ~]# kubectl apply -f replicaset.yml
[root@k8s-master ~]# kubectl get pods ?--show-labels
#replicaset是通過標簽匹配pod
[root@k8s-master ~]# kubectl label pod replicaset-bhm6t app=xie --overwrite
[root@k8s-master ~]# kubectl get pods ?--show-labels
#恢復標簽后
[root@k8s2 pod]# kubectl label pod replicaset-bhm6t app-
[root@k8s2 pod]# kubectl get pod --show-labels
#replicaset自動控制副本數量,pod可以自愈
[root@k8s-master ~]# kubectl delete pods replicaset- bhm6t
[root@k8s-master ~]# kubectl get pods --show-labels
回收資源
[root@master zuoye]# kubectl delete -f replicaset.yml
deployment 控制器
- 為了更好的解決服務編排的問題,kubernetes在V1.2版本開始,引入了Deployment控制器。
- Deployment控制器并不直接管理pod,而是通過管理ReplicaSet來間接管理Pod
- Deployment管理ReplicaSet,ReplicaSet管理Pod
- Deployment 為 Pod 和 ReplicaSet 提供了一個申明式的定義方法
- 在Deployment中ReplicaSet相當于一個版本
**典型的應用場景:**
- 用來創建Pod和ReplicaSet
- 滾動更新和回滾
- 擴容和縮容
- 暫停與恢復
deployment控制器示例
#生成yaml文件
[root@k8s-master ~]# kubectl create deployment deployment --image myapp:v1 ?--dry-run=client -o yaml > deployment.yml
[root@k8s-master ~]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? name: deployment
spec:
? replicas: 4
? selector:
? ? matchLabels:
? ? ? app: myapp
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: myapp
? ? spec:
? ? ? containers:
? ? ? - image: myapp:v1
? ? ? ? name: myapp
#建立pod
root@k8s-master ~]# kubectl apply -f deployment.yml
daemonset控制器
DaemonSet 確保全部(或者某些)節點上運行一個 Pod 的副本。當有節點加入集群時, 也會為他們新增一個 Pod ,當有節點從集群移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的所有 Pod
DaemonSet 的典型用法:
- 在每個節點上運行集群存儲 DaemonSet,例如 glusterd、ceph。
- 在每個節點上運行日志收集 DaemonSet,例如 fluentd、logstash。
- 在每個節點上運行監控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等
- 一個簡單的用法是在所有的節點上都啟動一個 DaemonSet,將被作為每種類型的 daemon 使用
- 一個稍微復雜的用法是單獨對每種 daemon 類型使用多個 DaemonSet,但具有不同的標志, 并且對不同硬件類型具有不同的內存、CPU 要求
daemonset 示例
[root@k8s2 pod]# cat daemonset-example.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
? name: daemonset-example
spec:
? selector:
? ? matchLabels:
? ? ? app: nginx
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx
? ? spec:
? ? ? tolerations: ? ?#對于污點節點的容忍
? ? ? - effect: NoSchedule
? ? ? ? operator: Exists
? ? ? containers:
? ? ? - name: nginx
? ? ? ? image: nginx
[root@k8s-master ~]# kubectl get pods ?-o wide
job 控制器
job控制器功能
Job,主要用于負責批量處理(一次要處理指定數量任務)短暫的一次性(每個任務僅運行一次就結束)任務
Job特點如下:
- 當Job創建的pod執行成功結束時,Job將記錄成功結束的pod數量
- 當成功結束的pod達到指定的數量時,Job將完成執行
job 控制器示例:
[root@k8s2 pod]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
? name: pi
spec:
? completions: 6 ? ?#一共完成任務數為6 ? ?
? parallelism: 2 ? ?#每次并行完成2個
? template:
? ? spec:
? ? ? containers:
? ? ? - name: pi
? ? ? ? image: perl:5.34.0
? ? ? ? command: ["perl", ?"-Mbignum=bpi", "-wle", "print bpi(2000)"] 計算Π的后2000位
? ? ? restartPolicy: Never ? ? ? ? ? ?#關閉后不自動重啟
? backoffLimit: 4 ? ? ? ? ? ? ? #運行失敗后嘗試4重新運行
[root@k8s2 pod]# kubectl apply -f job.yml
cronjob 控制器
- Cron Job 創建基于時間調度的 Jobs。
- CronJob控制器以Job控制器資源為其管控對象,并借助它管理pod資源對象,
- CronJob可以以類似于Linux操作系統的周期性任務作業計劃的方式控制其運行時間點及重復運行的方式。
- CronJob可以在特定的時間點(反復的)去運行job任務。
[root@k8s2 pod]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
? name: hello
spec:
? schedule: "* * * * *"
? jobTemplate:
? ? spec:
? ? ? template:
? ? ? ? spec:
? ? ? ? ? containers:
? ? ? ? ? - name: hello
? ? ? ? ? ? image: busybox
? ? ? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? ? ? command:
? ? ? ? ? ? - /bin/sh
? ? ? ? ? ? - -c
? ? ? ? ? ? - date; echo Hello from the Kubernetes cluster
? ? ? ? ? restartPolicy: OnFailure
[root@k8s2 pod]# kubectl apply -f cronjob.yml
k8s中的微服務
什么是微服務
用控制器來完成集群的工作負載,那么應用如何暴漏出去?需要通過微服務暴漏出去后才能被訪問
- ?Service是一組提供相同服務的Pod對外開放的接口。
- 借助Service,應用可以實現服務發現和負載均衡。
- ?service默認只支持4層負載均衡能力,沒有7層功能。(可以通過Ingress實現)
服務類型 | 核心作用 | 訪問方式 | 適用場景 | 關鍵特性 |
ClusterIP | 為集群內的 Pod 提供固定的內部訪問地址,實現集群內部服務通信 | 僅能通過集群內的?ClusterIP:Port?訪問(如?10.96.0.1:80) | 集群內部服務間通信(如前端服務調用后端 API、數據庫服務被應用訪問) | 1. 自動分配唯一的集群內部 IP(也可手動指定); |
NodePort | 在 ClusterIP 基礎上,通過在集群所有節點開放靜態端口,實現外部訪問集群服務 | 外部可通過?任意節點IP:NodePort?訪問(如?192.168.1.100:30080) | 開發 / 測試環境中臨時暴露服務(如外部訪問內部 API 進行調試) | 1. 會自動創建 ClusterIP,NodePort 是在其基礎上的擴展; |
LoadBalancer | 在 NodePort 基礎上,結合云廠商負載均衡器(或 MetalLB 等工具)提供外部訪問 | 外部通過負載均衡器分配的公網 IP / 域名訪問(如?http://10.1.2.3:80) | 生產環境中需要公網訪問的服務(如 Web 應用、對外 API 服務) | 1. 自動創建 NodePort 和 ClusterIP,底層依賴外部負載均衡器; |
ExternalName | 將 Service 映射到集群外部的域名(如外部數據庫、第三方 API),實現域名別名 | 集群內通過 Service 名稱訪問,自動解析為外部域名(如?external-service.default.svc.cluster.local?映射到?api.example.com) | 集群內服務需要訪問外部固定域名的服務(如連接云廠商托管數據庫、調用第三方 API) | 1. 不創建 ClusterIP 或端口,僅做域名映射; |
#生成控制器文件并建立控制器
[root@master zuoye]# kubectl create deployment xie --image myapp:v1? --replicas 2 --dry-run=client -o yaml > xie.yaml
[root@master zuoye]# kubectl create deployment xie --image myapp:v1? --replicas 2 --dry-run=client -o yaml >> xie.yaml
[root@k8s-master ~]# vim xie.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: xie
? name: xie
spec:
? replicas: 2
? selector:
? ? matchLabels:
? ? ? app: xie
? template:
? ? metadata:
? ? ? creationTimestamp: null
? ? ? labels:
? ? ? ? app: xie
? ? spec:
? ? ? containers:
? ? ? - image: myapp:v1
? ? ? ? name: myapp
---???????????????????????????????????????????????????????????????????????????? #不同資源間用---隔開
apiVersion: v1
kind: Service
metadata:
? labels:
??? app: xie
? name: xie
spec:
? ports:
? - port: 80
??? protocol: TCP
??? targetPort: 80
? selector:
??? app: xie
[root@master zuoye]# kubectl apply -f xie.yaml
[root@k8s-master ~]# kubectl get services
微服務默認使用iptables調度
ipvs模式
- Service 是由 kube-proxy 組件,加上 iptables 來共同實現的
- kube-proxy 通過 iptables 處理 Service 的過程,需要在宿主機上設置相當多的 iptables 規則,如果宿主機有大量的Pod,不斷刷新iptables規則,會消耗大量的CPU資源
- IPVS模式的service,可以使K8s集群支持更多量級的Pod
在所有節點中安裝ipvsadm
```bash
[root@k8s-所有節點 pod]yum install ipvsadm –y
[root@k8s-master ~]# kubectl -n kube-system edit cm kube-proxy
? ? metricsBindAddress: ""
? ? mode: "ipvs" ? ? ? ? ? ? ?#設置kube-proxy使用ipvs模式
? ? nftables:
重啟pod,在pod運行時配置文件中采用默認配置,當改變配置文件后已經運行的pod狀態不會變化,所以要重啟pod
微服務類型詳解
clusterip
特點:
clusterip模式只能在集群內訪問,并對集群內的pod提供健康檢測和自動發現功能
[root@k8s2 service]# vim myapp.yml
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: xie
? name: xie
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? app: xie
? type: ClusterIP
service創建后集群DNS提供解析
[root@k8s-master ~]# dig ?xie.default.svc.cluster.local @10.96.0.10
; <<>> DiG 9.16.23-RH <<>> xie.default.svc.cluster.local @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27827
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 057d9ff344fe9a3a (echoed)
;; QUESTION SECTION:
;xie.default.svc.cluster.local. IN ? ? ? ?A
;; ANSWER SECTION:
xie.default.svc.cluster.local. 30 IN A ? ?10.97.59.25
;; Query time: 8 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Wed Sep 04 13:44:30 CST 2024
;; MSG SIZE ?rcvd: 127
ClusterIP中的特殊模式headless
headless(無頭服務)
對于無頭 `Services` 并不會分配 Cluster IP,kube-proxy不會處理它們, 而且平臺也不會為它們進行負載均衡和路由,集群訪問通過dns解析直接指向到業務pod上的IP,所有的調度有dns單獨完成
[root@k8s-master ~]# vim xie.yaml
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: xie
? name: xie
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? app: xie
? type: ClusterIP
? clusterIP: None
[root@k8s-master ~]# kubectl delete -f xie.yaml
[root@k8s-master ~]# kubectl apply -f xie.yaml
#測試
[root@k8s-master ~]# kubectl get services xie
nodeport
通過ipvs暴漏端口從而使外部主機通過master節點的對外ip:<port>來訪問pod業務
[root@k8s-master ~]# vim xie.yaml
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: xie-service
? name: xie-service
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? app: xie
? type: NodePort
[root@k8s-master ~]# kubectl apply -f xie.yaml
[root@k8s-master ~]# kubectl get services ?xie-service
loadbalancer
云平臺會為我們分配vip并實現訪問,如果是裸金屬主機那么需要metallb來實現ip的分配
[root@k8s-master ~]# vim xie.yaml
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: xie-service
? name: xie-service
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? app: xie
? type: LoadBalancer
默認無法分配外部訪問IP
LoadBalancer模式適用云平臺,裸金屬環境需要安裝metallb提供支持
metalLB
metalLB功能,為LoadBalancer分配vip
部署方式
1.設置ipvs模式
[root@k8s-master ~]# kubectl edit cm -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
? strictARP: true
[root@k8s-master ~]# kubectl -n kube-system get ?pods ? | awk '/kube-proxy/{system("kubectl -n kube-system delete pods "$1)}'
2.下載部署文件
[root@k8s2 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml
3.修改文件中鏡像地址,與harbor倉庫路徑保持一致
[root@k8s-master ~]# vim metallb-native.yaml
4.上傳鏡像到harbor
部署服務
[root@k8s2 metallb]# kubectl apply -f metallb-native.yaml
[root@k8s-master ~]# kubectl -n metallb-system get pods
配置分配地址段
[root@k8s-master ~]# vim configmap.yml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
? name: first-pool ? ? ? ? ? ?#地址池名稱
? namespace: metallb-system
spec:
? addresses:
? - 172.25.254.50-172.25.254.99 ? ? #修改為自己本地地址段
--- ? ? ? ? ? ? ? ? ? #兩個不同的kind中間必須加分割
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
? name: example
? namespace: metallb-system
spec:
? ipAddressPools:
? - first-pool ? ? ? ? ? ? ?#使用地址池
[root@k8s-master ~]# kubectl apply -f configmap.yml
[root@k8s-master ~]# kubectl get services
#通過分配地址從集群外訪問服務
externalname
- 開啟services后,不會被分配IP,而是用dns解析CNAME固定域名來解決ip變化問題
- 一般應用于外部業務和pod溝通或外部業務遷移到pod內時
- 在應用向集群遷移過程中,externalname在過度階段就可以起作用了。
- 集群外的資源遷移到集群時,在遷移的過程中ip可能會變化,但是域名+dns解析能完美解決此問題
[root@k8s-master ~]# vim xie.yaml
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: xie-service
? name: xie-service
spec:
? selector:
? ? app: xie
? type: ExternalName
? externalName: www.xie.org
[root@k8s-master ~]# kubectl apply -f xie.yaml
[root@k8s-master ~]# kubectl get services ?xie-service
Ingress-nginx
- 一種全局的、為了代理不同后端 Service 而設置的負載均衡服務,支持7層
- Ingress由兩部分組成:Ingress controller和Ingress服務
- Ingress Controller 會根據你定義的 Ingress 對象,提供對應的代理能力。
- 業界常用的各種反向代理項目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已經為Kubernetes 專門維護了對應的 Ingress Controller。
部署ingress
下載部署文件
[root@k8s-master ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/baremetal/deploy.yaml
上傳ingress所需鏡像到harbor
[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/controller:v1.11.2@sha256:d5f8217feeac4887cb1ed21f27c2674e58be06bd8f5184cacea2a69abaf78dce reg.xie.org/ingress-nginx/controller:v1.11.2
[root@k8s-master ~]# docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3@sha256:a320a50cc91bd15fd2d6fa6de58bd98c1bd64b9a6f926ce23a600d87043455a3 reg.xie.org/ingress-nginx/kube-webhook-certgen:v1.4.3
[root@k8s-master ~]# docker push reg.xie.org/ingress-nginx/controller:v1.11.2
[root@k8s-master ~]# docker push reg.xie.org/ingress-nginx/kube-webhook-certgen:v1.4.3
安裝ingress
[root@k8s-master ~]# vim deploy.yaml
445 ? ? ? ? image: ingress-nginx/controller:v1.11.2
546 ? ? ? ? image: ingress-nginx/kube-webhook-certgen:v1.4.3
599 ? ? ? ? image: ingress-nginx/kube-webhook-certgen:v1.4.3
[root@k8s-master app]# vim myapp-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: myapp-v1
? name: myapp-v1
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? app: myapp-v1
? strategy: {}
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: myapp-v1
? ? spec:
? ? ? containers:
? ? ? - image: myapp:v1
? ? ? ? name: myapp
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: myapp-v1
? name: myapp-v1
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? app: myapp-v1
[root@k8s-master app]# vim myapp-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: myapp-v2
? name: myapp-v2
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? app: myapp-v2
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: myapp-v2
? ? spec:
? ? ? containers:
? ? ? - image: myapp:v2
? ? ? ? name: myapp
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? app: myapp-v2
? name: myapp-v2
spec:
? ports:
? - port: 80
? ? protocol: TCP
? ? targetPort: 80
? selector:
? ? app: myapp-v2
[root@k8s-master app]# kubectl expose deployment myapp-v1 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yaml
[root@k8s-master app]# kubectl expose deployment myapp-v2 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yaml
基于域名的訪問
[root@reg ~]# vim /etc/hosts
172.25.254.50 www.xie.org myappv1.xie.org myappv2.xie.org
# 建立基于域名的yml文件
[root@k8s-master app]# vim ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
? annotations:
? ? nginx.ingress.kubernetes.io/rewrite-target: /
? name: ingress2
spec:
? ingressClassName: nginx
? rules:
? - host: myappv1.xie.org
? ? http:
? ? ? paths:
? ? ? - backend:
? ? ? ? ? service:
? ? ? ? ? ? name: myapp-v1
? ? ? ? ? ? port:
? ? ? ? ? ? ? number: 80
? ? ? ? path: /
? ? ? ? pathType: Prefix
? - host: myappv2.xie.org
? ? http:
? ? ? paths:
? ? ? - backend:
? ? ? ? ? service:
? ? ? ? ? ? name: myapp-v2
? ? ? ? ? ? port:
? ? ? ? ? ? ? number: 80
? ? ? ? path: /
? ? ? ? pathType: Prefix
[root@k8s-master app]# kubectl expose deployment myapp-v1 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yaml
[root@k8s-master app]# kubectl expose deployment myapp-v2 --port 80 --target-port 80 --dry-run=client -o yaml >> myapp-v1.yaml
#利用文件建立ingress
[root@k8s-master app]# kubectl apply -f ingress.yml
[root@k8s-master app]# kubectl describe ingress ingress2
Canary金絲雀發布
什么是金絲雀發布
金絲雀發布(Canary Release)也稱為灰度發布,是一種軟件發布策略。
主要目的是在將新版本的軟件全面推廣到生產環境之前,先在一小部分用戶或服務器上進行測試和驗證,以降低因新版本引入重大問題而對整個系統造成的影響。
是一種Pod的發布方式。金絲雀發布采取先添加、再刪除的方式,保證Pod的總量不低于期望值。并且在更新部分Pod后,暫停更新,當確認新Pod版本運行正常后再進行其他版本的Pod的更新。
基于header(http包頭)灰度
- 通過Annotaion擴展
- 創建灰度ingress,配置灰度頭部key以及value
- 灰度流量驗證完畢后,切換正式ingress到新版本
- 之前我們在做升級時可以通過控制器做滾動更新,默認25%利用header可以使升級更為平滑,通過key 和vule 測試新的業務體系是否有問題。
[root@k8s-master app]# vim ingress7.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
? annotations:
? name: myapp-v1-ingress
spec:
? ingressClassName: nginx
? rules:
? - host: myapp.xie.org
? ? http:
? ? ? paths:
? ? ? - backend:
? ? ? ? ? service:
? ? ? ? ? ? name: myapp-v1
? ? ? ? ? ? port:
? ? ? ? ? ? ? number: 80
? ? ? ? path: /
? ? ? ? pathType: Prefix
kubernetes下的存儲管理
configmap的功能
- configMap用于保存配置數據,以鍵值對形式存儲。
- configMap 資源提供了向 Pod 注入配置數據的方法。
- 鏡像和配置文件解耦,以便實現鏡像的可移植性和可復用性。
- etcd限制了文件大小不能超過1M
configmap的使用場景
- 填充環境變量的值
- 設置容器內的命令行參數
- 填充卷的配置文件
configmap創建方式
字面值創建,通過文件創建,通過目錄創建,通過yaml文件創建
configmap的使用方式
- 通過環境變量的方式直接傳遞給pod
- 通過pod的 命令行運行方式
- 作為volume的方式掛載到pod內
使用configmap填充環境變量
[root@k8s-master ~]# vim testpod1.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: testpod
? name: testpod
spec:
? containers:
? - image: busyboxplus:latest
? ? name: testpod
? ? command:
? ? - /bin/sh
? ? - -c
? ? - env
? ? env:
? ? - name: key1
? ? ? valueFrom:
? ? ? ? configMapKeyRef:
? ? ? ? ? name: lee4-config
? ? ? ? ? key: db_host
? ? - name: key2
? ? ? valueFrom:
? ? ? ? configMapKeyRef:
? ? ? ? ? name: lee4-config
? ? ? ? ? key: db_port
? restartPolicy: Never
[root@k8s-master ~]# kubectl apply -f testpod.yml
[root@k8s-master ~]# kubectl logs pods/testpod
通過數據卷使用configmap
[root@k8s-master ~]# vim testpod4.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: testpod
? name: testpod
spec:
? containers:
? - image: busyboxplus:latest
? ? name: testpod
? ? command:
? ? - /bin/sh
? ? - -c
? ? - cat /config/db_host
? ? volumeMounts: ? ? ? ? #調用卷策略
? ? - name: config-volume ? ? #卷名稱
? ? ? mountPath: /config
? volumes: ? ? ? ? ? ? ?#聲明卷的配置
? - name: config-volume ? ? ? #卷名稱
? ? configMap:
? ? ? name: lee4-config
? restartPolicy: Never
#查看日志
[root@k8s-master ~]# kubectl logs testpod
利用configMap填充pod的配置文件
#建立配置文件模板
[root@k8s-master ~]# vim nginx.conf
server {
? listen 8000;
? server_name _;
? root /usr/share/nginx/html;
? index index.html;
}
#利用模板生成cm
root@k8s-master ~]# kubectl create cm nginx-conf --from-file nginx.conf
configmap/nginx-conf created
[root@k8s-master ~]# kubectl describe cm nginx-conf
#建立nginx控制器文件
[root@k8s-master ~]# kubectl create deployment nginx --image nginx:latest --replicas 1 --dry-run=client -o yaml > nginx.yml
#設定nginx.yml中的卷
[root@k8s-master ~]# vim nginx.yml
[root@k8s-master ~]# cat nginx.
cat: nginx.: 沒有那個文件或目錄
[root@k8s-master ~]# cat nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: nginx
? name: nginx
spec:
? replicas: 1
? selector:
? ? matchLabels:
? ? ? app: nginx
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx
? ? spec:
? ? ? containers:
? ? ? - image: nginx:latest
? ? ? ? name: nginx
? ? ? ? volumeMounts:
? ? ? ? - name: config-volume
? ? ? ? ? mountPath: /etc/nginx/conf.d
? ? ? volumes:
? ? ? ? - name: config-volume
? ? ? ? ? configMap:
? ? ? ? ? ? name: nginx-conf
#測試
[root@k8s-master ~]# kubectl get pods -o wide
[root@master zuoye]#? curl 10.244.104.8:8000
secrets配置管理
secrets的功能介紹
- Secret 對象類型用來保存敏感信息,例如密碼、OAuth 令牌和 ssh key。
- ?敏感信息放在 secret 中比放在 Pod 的定義或者容器鏡像中來說更加安全和靈活
- Pod 可以用兩種方式使用 secret:
? - 作為 volume 中的文件被掛載到 pod 中的一個或者多個容器里。
? - 當 kubelet 為 pod 拉取鏡像時使用。
- Secret的類型:
? - Service Account:Kubernetes 自動創建包含訪問 API 憑據的 secret,并自動修改 pod 以使用此類型的 secret。
? - Opaque:使用base64編碼存儲信息,可以通過base64 --decode解碼獲得原始數據,因此安全性弱。
? - kubernetes.io/dockerconfigjson:用于存儲docker registry的認證信息
?secrets的創建
在創建secrets時我們可以用命令的方法或者yaml文件的方法
從文件創建
```bash
[root@k8s-master secrets]# echo -n xie > username.txt
[root@k8s-master secrets]# echo -n lee > password.txt
root@k8s-master secrets]# kubectl create secret generic userlist --from-file username.txt --from-file password.txt
secret/userlist created
[root@k8s-master secrets]# kubectl get secrets userlist -o yaml
編寫yaml文件
```bash
[root@k8s-master secrets]# echo -n xie | base64
dGltaW5nbGVl
[root@k8s-master secrets]# echo -n lee | base64
bGVl
[root@k8s-master secrets]# kubectl create secret generic userlist --dry-run=client -o yaml > userlist.yml
[root@k8s-master secrets]# vim userlist.yml
apiVersion: v1
kind: Secret
metadata:
? creationTimestamp: null
? name: userlist
type: Opaque
data:
? username: dGltaW5nbGVl
? password: bGVl
[root@k8s-master secrets]# kubectl apply -f userlist.yml
[root@k8s-master secrets]# kubectl describe secrets userlist
Secret的使用方法
將Secret掛載到Volume中
[root@k8s-master secrets]# kubectl run ?nginx --image nginx --dry-run=client -o yaml > pod1.yaml
#向固定路徑映射
[root@k8s-master secrets]# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: nginx
? name: nginx
spec:
? containers:
? - image: nginx
? ? name: nginx
? ? volumeMounts:
? ? - name: secrets
? ? ? mountPath: /secret
? ? ? readOnly: true
? volumes:
? - name: secrets
? ? secret:
? ? ? secretName: userlist
[root@k8s-master secrets]# kubectl apply -f pod1.yaml
[root@k8s-master secrets]# kubectl exec ?pods/nginx -it -- /bin/bash
k8s下的網絡通信與調度
k8s通信整體架構
- k8s通過CNI接口接入其他插件來實現網絡通訊。目前比較流行的插件有flannel,calico等
- CNI插件存放位置:# cat /etc/cni/net.d/10-flannel.conflist
- 插件使用的解決方案如下
? - 虛擬網橋,虛擬網卡,多個容器共用一個虛擬網卡進行通信。
? - 多路復用:MacVLAN,多個容器共用一個物理網卡進行通信。
? - 硬件交換:SR-LOV,一個物理網卡可以虛擬出多個接口,這個性能最好。
- 容器間通信:
? - 同一個pod內的多個容器間的通信,通過lo即可實現pod之間的通信
? - 同一節點的pod之間通過cni網橋轉發數據包。
? - 不同節點的pod之間的通信需要網絡插件支持
- pod和service通信: 通過iptables或ipvs實現通信,ipvs取代不了iptables,因為ipvs只能做負載均衡,而做不了nat轉換
- pod和外網通信:iptables的MASQUERADE
- Service與集群外部客戶端的通信;(ingress、nodeport、loadbalancer)
flannel網絡插件
插件組成:
| 插件 ? ? ?| 功能 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| --------- | ------------------------------------------------------------ |
| VXLAN ? ? | 即Virtual ?Extensible LAN(虛擬可擴展局域網),是Linux本身支持的一網種網絡虛擬化技術。VXLAN可以完全在內核態實現封裝和解封裝工作,從而通過“隧道”機制,構建出覆蓋網絡(Overlay Network) |
| VTEP ? ? ?| VXLAN Tunnel ?End Point(虛擬隧道端點),在Flannel中 VNI的默認值是1,這也是為什么宿主機的VTEP設備都叫flannel.1的原因 |
| Cni0 ? ? ?| 網橋設備,每創建一個pod都會創建一對 veth pair。其中一端是pod中的eth0,另一端是Cni0網橋中的端口(網卡) |
| Flannel.1 | TUN設備(虛擬網卡),用來進行 vxlan 報文的處理(封包和解包)。不同node之間的pod數據流量都從overlay設備以隧道的形式發送到對端 |
| Flanneld ?| flannel在每個主機中運行flanneld作為agent,它會為所在主機從集群的網絡地址空間中,獲取一個小的網段subnet,本主機內所有容器的IP地址都將從中分配。同時Flanneld監聽K8s集群數據庫,為flannel.1設備提供封裝數據時必要的mac、ip等網絡數據信息 |
### flannel跨主機通信原理
- 當容器發送IP包,通過veth pair 發往cni網橋,再路由到本機的flannel.1設備進行處理。
- VTEP設備之間通過二層數據幀進行通信,源VTEP設備收到原始IP包后,在上面加上一個目的MAC地址,封裝成一個內部數據幀,發送給目的VTEP設備。
- 內部數據楨,并不能在宿主機的二層網絡傳輸,Linux內核還需要把它進一步封裝成為宿主機的一個普通的數據幀,承載著內部數據幀通過宿主機的eth0進行傳輸。
- Linux會在內部數據幀前面,加上一個VXLAN頭,VXLAN頭里有一個重要的標志叫VNI,它是VTEP識別某個數據楨是不是應該歸自己處理的重要標識。
- flannel.1設備只知道另一端flannel.1設備的MAC地址,卻不知道對應的宿主機地址是什么。在linux內核里面,網絡設備進行轉發的依據,來自FDB的轉發數據庫,這個flannel.1網橋對應的FDB信息,是由flanneld進程維護的。
- linux內核在IP包前面再加上二層數據幀頭,把目標節點的MAC地址填進去,MAC地址從宿主機的ARP表獲取。
- 此時flannel.1設備就可以把這個數據幀從eth0發出去,再經過宿主機網絡來到目標節點的eth0設備。目標主機內核網絡棧會發現這個數據幀有VXLAN Header,并且VNI為1,Linux內核會對它進行拆包,拿到內部數據幀,根據VNI的值,交給本機flannel.1設備處理,flannel.1拆包,根據路由表發往cni網橋,最后到達目標容器。
calico網絡插件
?calico簡介:
- 純三層的轉發,中間沒有任何的NAT和overlay,轉發效率最好。
- Calico 僅依賴三層路由可達。Calico 較少的依賴性使它能適配所有 VM、Container、白盒或者混合環境場景。
calico網絡架構
- Felix:監聽ECTD中心的存儲獲取事件,用戶創建pod后,Felix負責將其網卡、IP、MAC都設置好,然后在內核的路由表里面寫一條,注明這個IP應該到這張網卡。同樣如果用戶制定了隔離策略,Felix同樣會將該策略創建到ACL中,以實現隔離。
- BIRD:一個標準的路由程序,它會從內核里面獲取哪一些IP的路由發生了變化,然后通過標準BGP的路由協議擴散到整個其他的宿主機上,讓外界都知道這個IP在這里,路由的時候到這里
下載部署文件
[root@k8s-master calico]# curl https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/calico-typha.yaml -o calico.yaml
下載鏡像上傳至倉庫:
```bash
[root@k8s-master ~]# docker pull docker.io/calico/cni:v3.28.1
[root@k8s-master ~]# docker pull docker.io/calico/node:v3.28.1
[root@k8s-master ~]# docker pull docker.io/calico/kube-controllers:v3.28.1
[root@k8s-master ~]# docker pull docker.io/calico/typha:v3.28.1
更改yml設置
```bash
[root@k8s-master calico]# vim calico.yaml
4835 ? ? ? ? ? image: calico/cni:v3.28.1
4835 ? ? ? ? ? image: calico/cni:v3.28.1
4906 ? ? ? ? ? image: calico/node:v3.28.1
4932 ? ? ? ? ? image: calico/node:v3.28.1
5160 ? ? ? ? ? image: calico/kube-controllers:v3.28.1
5249 ? ? ? ? - image: calico/typha:v3.28.1
4970 ? ? ? ? ? ? - name: CALICO_IPV4POOL_IPIP
4971 ? ? ? ? ? ? ? value: "Never"
4999 ? ? ? ? ? ? - name: CALICO_IPV4POOL_CIDR
5000 ? ? ? ? ? ? ? value: "10.244.0.0/16"
5001 ? ? ? ? ? ? - name: CALICO_AUTODETECTION_METHOD
5002 ? ? ? ? ? ? ? value: "interface=eth0"
[root@k8s-master calico]# kubectl apply -f calico.yaml
[root@k8s-master calico]# kubectl -n kube-system get pods
k8s調度(Scheduling)
?調度在Kubernetes中的作用
- 調度是指將未調度的Pod自動分配到集群中的節點的過程
- 調度器通過 kubernetes 的 watch 機制來發現集群中新創建且尚未被調度到 Node 上的 Pod
- 調度器會將發現的每一個未調度的 Pod 調度到一個合適的 Node 上來運行
調度原理:
- 創建Pod
? - 用戶通過Kubernetes API創建Pod對象,并在其中指定Pod的資源需求、容器鏡像等信息。
- 調度器監視Pod
? - Kubernetes調度器監視集群中的未調度Pod對象,并為其選擇最佳的節點。
- 選擇節點
? - 調度器通過算法選擇最佳的節點,并將Pod綁定到該節點上。調度器選擇節點的依據包括節點的資源使用情況、Pod的資源需求、親和性和反親和性等。
- 綁定Pod到節點
? - 調度器將Pod和節點之間的綁定信息保存在etcd數據庫中,以便節點可以獲取Pod的調度信息。
- 節點啟動Pod
? - 節點定期檢查etcd數據庫中的Pod調度信息,并啟動相應的Pod。如果節點故障或資源不足,調度器會重新調度Pod,并將其綁定到其他節點上運行。
調度器種類
- 默認調度器(Default Scheduler):
? - 是Kubernetes中的默認調度器,負責對新創建的Pod進行調度,并將Pod調度到合適的節點上。
- 自定義調度器(Custom Scheduler):
? - 是一種自定義的調度器實現,可以根據實際需求來定義調度策略和規則,以實現更靈活和多樣化的調度功能。
- 擴展調度器(Extended Scheduler):
? - 是一種支持調度器擴展器的調度器實現,可以通過調度器擴展器來添加自定義的調度規則和策略,以實現更靈活和多樣化的調度功能。
- kube-scheduler是kubernetes中的默認調度器,在kubernetes運行后會自動在控制節點運行
常用調度方法
nodename
- nodeName 是節點選擇約束的最簡單方法,但一般不推薦
- 如果 nodeName 在 PodSpec 中指定了,則它優先于其他的節點選擇方法
- 使用 nodeName 來選擇節點的一些限制
? - 如果指定的節點不存在。
? - 如果指定的節點沒有資源來容納 pod,則pod 調度失敗。
? - 云環境中的節點名稱并非總是可預測或穩定的
實例:
```bash
#建立pod文件
[[root@k8s-master scheduler]# kubectl run ?testpod ?--image myapp:v1 --dry-run=client -o yaml > pod1.yml
#設置調度
[root@k8s-master scheduler]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
? labels:
? ? run: testpod
? name: testpod
spec:
? nodeName: k8s-node2
? containers:
? - image: myapp:v1
? ? name: testpod
#建立pod
[root@k8s-master scheduler]# kubectl apply -f pod1.yml
[root@k8s-master scheduler]# kubectl get pods ?-o wide
NAME ? ? ?READY ? STATUS ? ?RESTARTS ? AGE ? IP ? ? ? ? ? ? ? NODE ? ? ? ?NOMINATED NODE ? READINESS GATES
testpod ? 1/1 ? ? Running ? 0 ? ? ? ? ?18s ? 10.244.169.130 ?
affinity(親和性)
親和與反親和
- nodeSelector 提供了一種非常簡單的方法來將 pod 約束到具有特定標簽的節點上。親和/反親和功能極大地擴展了你可以表達約束的類型。
- 使用節點上的 pod 的標簽來約束,而不是使用節點本身的標簽,來允許哪些 pod 可以或者不可以被放置在一起。
nodeAffinity節點親和
- 那個節點服務指定條件就在那個節點運行
- requiredDuringSchedulingIgnoredDuringExecution ? 必須滿足,但不會影響已經調度
- preferredDuringSchedulingIgnoredDuringExecution 傾向滿足,在無法滿足情況下也會調度pod
? - IgnoreDuringExecution 表示如果在Pod運行期間Node的標簽發生變化,導致親和性策略不能滿足,則繼續運行當前的Pod。
- nodeaffinity還支持多種規則匹配條件的配置如
| 匹配規則 ? ? | 功能 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|
| ------------ | --------------------------------------- |
| ln ? ? ? ? ? | label 的值在列表內 ? ? ? ? ? ? ? ? ? ? ?|
| Notln ? ? ? ?| label 的值不在列表內 ? ? ? ? ? ? ? ? ? ?|
| Gt ? ? ? ? ? | label 的值大于設置的值,不支持Pod親和性 |
| Lt ? ? ? ? ? | label 的值小于設置的值,不支持pod親和性 |
| Exists ? ? ? | 設置的label 存在 ? ? ? ? ? ? ? ? ? ? ? ?|
| DoesNotExist | 設置的 label 不存在 ? ? ? ? ? ? ? ? ? ? |
nodeAffinity示例
[root@k8s-master scheduler]# vim pod3.yml
apiVersion: v1
kind: Pod
metadata:
? name: node-affinity
spec:
? containers:
? - name: nginx
? ? image: nginx
? affinity:
? ? nodeAffinity:
? ? ? requiredDuringSchedulingIgnoredDuringExecution:
? ? ? ? ? ?nodeSelectorTerms:
? ? ? ? ? ?- matchExpressions:
? ? ? ? ? ? ?- key: disk
? ? ? ? ? ? ? ?operator: In | NotIn ? ? #兩個結果相反
? ? ? ? ? ? ? ?values:
? ? ? ? ? ? ? ? ?- ssd
Podaffinity示例
[root@k8s-master scheduler]# vim example4.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? name: nginx-deployment
? labels:
? ? app: nginx
spec:
? replicas: 3
? selector:
? ? matchLabels:
? ? ? app: nginx
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx
? ? spec:
? ? ? containers:
? ? ? - name: nginx
? ? ? ? image: nginx
? ? ? affinity:
? ? ? ? podAffinity:
? ? ? ? ? requiredDuringSchedulingIgnoredDuringExecution:
? ? ? ? ? - labelSelector:
? ? ? ? ? ? ? matchExpressions:
? ? ? ? ? ? ? - key: app
? ? ? ? ? ? ? ? operator: In
? ? ? ? ? ? ? ? values:
? ? ? ? ? ? ? ? - nginx
? ? ? ? ? ? topologyKey: "kubernetes.io/hostname"
[root@k8s-master scheduler]# kubectl get pods ?-o wide
?Podantiaffinity(pod反親和)
[root@k8s-master scheduler]# vim example5.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? name: nginx-deployment
? labels:
? ? app: nginx
spec:
? replicas: 3
? selector:
? ? matchLabels:
? ? ? app: nginx
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: nginx
? ? spec:
? ? ? containers:
? ? ? - name: nginx
? ? ? ? image: nginx
? ? ? affinity:
? ? ? ? podAntiAffinity: ? ?#反親和
? ? ? ? ? requiredDuringSchedulingIgnoredDuringExecution:
? ? ? ? ? - labelSelector:
? ? ? ? ? ? ? matchExpressions:
? ? ? ? ? ? ? - key: app
? ? ? ? ? ? ? ? operator: In
? ? ? ? ? ? ? ? values:
? ? ? ? ? ? ? ? - nginx
? ? ? ? ? ? topologyKey: "kubernetes.io/hostname"
[root@k8s-master scheduler]# kubectl get pods ?-o wide
Taints(污點模式,禁止調度
- Taints(污點)是Node的一個屬性,設置了Taints后,默認Kubernetes是不會將Pod調度到這個Node上
- Kubernetes如果為Pod設置Tolerations(容忍),只要Pod能夠容忍Node上的污點,那么Kubernetes就會忽略Node上的污點,就能夠(不是必須)把Pod調度過去
- 可以使用命令 kubectl taint 給節點增加一個 taint:
```
$ kubectl taint nodes <nodename> key=string:effect ? #命令執行方法
$ kubectl taint nodes node1 key=value:NoSchedule ? ?#創建
$ kubectl describe nodes server1 | grep Taints ? ? ? ?#查詢
$ kubectl taint nodes node1 key- ? ? ? ? ? ? ? ? ?#刪除
其中[effect] 可取值:
| effect值 ? ? ? ? | 解釋 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| ---------------- | ------------------------------------------------------------ |
| NoSchedule ? ? ? | POD 不會被調度到標記為 taints 節點 ? ? ? ? ? ? ? ? ? ? ? ? ? |
| PreferNoSchedule | NoSchedule 的軟策略版本,盡量不調度到此節點 ? ? ? ? ? ? ? ? ?|
| NoExecute ? ? ? ?| 如該節點內正在運行的 POD 沒有對應 Tolerate 設置,會直接被逐出 |
#建立控制器并運行
[root@k8s-master scheduler]# vim example6.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: web
? name: web
spec:
? replicas: 2
? selector:
? ? matchLabels:
? ? ? app: web
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: web
? ? spec:
? ? ? containers:
? ? ? - image: nginx
? ? ? ? name: nginx
[root@k8s-master scheduler]# kubectl apply -f example6.yml
#設定污點為NoSchedule
[root@k8s-master scheduler]# kubectl taint node node1
[root@k8s-master scheduler]# kubectl describe nodes k8s-node1 | grep Tain
#刪除污點
[root@k8s-master scheduler]# kubectl describe nodes node1 | grep Tain
tolerations(污點容忍)
- tolerations中定義的key、value、effect,要與node上設置的taint保持一直:
? - 如果 operator 是 Equal ,則key與value之間的關系必須相等。
? - 如果 operator 是 Exists ,value可以省略
? - 如果不指定operator屬性,則默認值為Equal。
- 還有兩個特殊值:
? - 當不指定key,再配合Exists 就能匹配所有的key與value ,可以容忍所有污點。
? - 當不指定effect ,則匹配所有的effect
#### 污點容忍示例:
```bash
#設定節點污點
[root@k8s-master scheduler]# kubectl taint node k8s-node1 name=lee:NoExecute
node/k8s-node1 tainted
[root@k8s-master scheduler]# kubectl taint node k8s-node2 nodetype=bad:NoSchedule
node/k8s-node2 tainted
[root@k8s-master scheduler]# vim example7.yml
apiVersion: apps/v1
kind: Deployment
metadata:
? labels:
? ? app: web
? name: web
spec:
? replicas: 6
? selector:
? ? matchLabels:
? ? ? app: web
? template:
? ? metadata:
? ? ? labels:
? ? ? ? app: web
? ? spec:
? ? ? containers:
? ? ? - image: nginx
? ? ? ? name: nginx
? ? ?
? ? ? tolerations: ? ? ? ?#容忍所有污點
? ? ? - operator: Exists
? ?
? ? tolerations: ? ? ? ?#容忍effect為Noschedule的污點
? ? ? - operator: Exists
? ? ? ? effect: NoSchedule
?
? ? tolerations: ? ? ? ?#容忍指定kv的NoSchedule污點
? ? ? - key: nodetype
? ? ? ? value: bad
? ? ? ? effect: NoSchedule
```
> [!NOTE]
>
> 三種容忍方式每次測試寫一個即可
kubernetes中的認證授權
Authentication(認證)
- 認證方式現共有8種,可以啟用一種或多種認證方式,只要有一種認證方式通過,就不再進行其它方式的認證。通常啟用X509 Client Certs和Service Accout Tokens兩種認證方式。
- Kubernetes集群有兩類用戶:由Kubernetes管理的Service Accounts (服務賬戶)和(Users Accounts) 普通賬戶。k8s中賬號的概念不是我們理解的賬號,它并不真的存在,它只是形式上存在。
Authorization(授權)
- 必須經過認證階段,才到授權請求,根據所有授權策略匹配請求資源屬性,決定允許或拒絕請求。授權方式現共有6種,AlwaysDeny、AlwaysAllow、ABAC、RBAC、Webhook、Node。默認集群強制開啟RBAC。
認證(在k8s中建立認證用戶)
創建UserAccount
#建立證書
[root@k8s-master auth]# cd /etc/kubernetes/pki/
[root@k8s-master pki]# openssl genrsa -out timinglee.key 2048
[root@k8s-master pki]# openssl req ?-new -key timinglee.key -out timinglee.csr -subj "/CN=timinglee"
[root@k8s-master pki]# openssl x509 -req ?-in timinglee.csr -CA ca.crt -CAkey ca.key -CAcreateserial ?-out timinglee.crt -days 365
#建立k8s中的用戶
[root@k8s-master pki]# kubectl config set-credentials timinglee --client-certificate /etc/kubernetes/pki/timinglee.crt --client-key /etc/kubernetes/pki/timinglee.key --embed-certs=true
User "timinglee" set.
[root@k8s-master pki]# kubectl config view
#為用戶創建集群的安全上下文
root@k8s-master pki]# kubectl config set-context timinglee@kubernetes --cluster kubernetes --user timinglee
#切換用戶,用戶在集群中只有用戶身份沒有授權
[root@k8s-master ~]# kubectl config use-context timinglee@kubernetes
Switched to context "timinglee@kubernetes".
[root@k8s-master ~]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "timinglee" cannot list resource "pods" in API group "" in the namespace "default"
#切換會集群管理
[root@k8s-master ~]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
#如果需要刪除用戶
[root@k8s-master pki]# kubectl config delete-user timinglee
deleted user timinglee from /etc/kubernetes/admin.conf
```
RBAC(Role Based Access Control)
基于角色訪問控制授權:
- 允許管理員通過Kubernetes API動態配置授權策略。RBAC就是用戶通過角色與權限進行關聯。
- RBAC只有授權,沒有拒絕授權,所以只需要定義允許該用戶做什么即可
- RBAC的三個基本概念
? - Subject:被作用者,它表示k8s中的三類主體, user, group, serviceAccount
? - Role:角色,它其實是一組規則,定義了一組對 Kubernetes API 對象的操作權限。
? - RoleBinding:定義了“被作用者”和“角色”的綁定關系
- RBAC包括四種類型:Role、ClusterRole、RoleBinding、ClusterRoleBinding
- Role 和 ClusterRole
? - Role是一系列的權限的集合,Role只能授予單個namespace 中資源的訪問權限。
? - ClusterRole 跟 Role 類似,但是可以在集群中全局使用。
? - Kubernetes 還提供了四個預先定義好的 ClusterRole 來供用戶直接使用
? - cluster-amdin、admin、edit、view
role授權實施
#生成role的yaml文件
[root@k8s-master rbac]# kubectl create role myrole --dry-run=client --verb=get --resource pods -o yaml > myrole.yml
#更改文件內容
[root@k8s-master rbac]# vim myrole.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
? creationTimestamp: null
? name: myrole
rules:
- apiGroups:
? - ""
? resources:
? - pods
? verbs:
? - get
? - watch
? - list
? - create
? - update
? - path
? - delete
#創建role
[root@k8s-master rbac]# kubectl apply -f ?myrole.yml
[root@k8s-master rbac]# kubectl describe role myrole
[root@k8s-master rbac]# kubectl create rolebinding timinglee --role myrole --namespace default --user timinglee --dry-run=client -o yaml ?> rolebinding-myrole.yml
[root@k8s-master rbac]# vim rolebinding-myrole.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
? name: timinglee
? namespace: default ? ?#角色綁定必須指定namespace
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: Role
? name: myrole
subjects:
- apiGroup: rbac.authorization.k8s.io
? kind: User
? name: timinglee
[root@k8s-master rbac]# kubectl apply -f rolebinding-myrole.yml
rolebinding.rbac.authorization.k8s.io/timinglee created
[root@k8s-master rbac]# kubectl get rolebindings.rbac.authorization.k8s.io timinglee
#切換用戶測試授權
[root@k8s-master rbac]# kubectl config use-context timinglee@kubernetes
Switched to context "timinglee@kubernetes".
[root@k8s-master rbac]# kubectl get pods
No resources found in default namespace.
[root@k8s-master rbac]# kubectl get svc ? ? #只針對pod進行了授權,所以svc依然不能操作
Error from server (Forbidden): services is forbidden: User "timinglee" cannot list resource "services" in API group "" in the namespace "default"
#切換回管理員
[root@k8s-master rbac]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
#切換回管理員
[root@k8s-master rbac]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".