? ? ? ? 本文將深入探討Kubernetes中的核心資源對象,包括Pod、Deployment、Service、Ingress、ConfigMap和Secret,詳細解析其概念、功能以及實際應用場景,幫助讀者全面掌握這些關鍵組件的使用方法。
一、pod
1?pod概念
? ? ? ?k8s最小調度單元,可以包含一個或多個容器。同一個pod的容器可以共享網絡和存儲。
2 pod示例
[root@master-1 pod]# cat 02-pods-nginx.yaml
apiVersion: v1
kind: Pod
metadata:name: linux86-web
spec:containers:- name: webimage: nginx:1.24.0-alpineports:- containerPort: 80
[root@master-1 pod]# kubectl apply -f 02-pods-nginx.yaml
[root@master-1 pod]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
linux86-web 1/1 Running 0 82s 10.100.2.4 worker233 <none> <none>
[root@master-1 pod]# curl -I 10.100.2.4
二、deployment
1 介紹
Deployment是用于部署服務的資源,是最常用的控制器
- 管理RS,通過RS資源創建Pod;
- 具有上線部署,副本設置,滾動升級,回滾等功能;
- 提供聲明式更新,即可以使用apply命令進行更新鏡像版本之類的;
2 更新策略
藍綠發布:不停止舊版本,直接部署新版本,新版本測試沒有問題,就切換到新版本。
? ? ? ?優點:無需停機,風險較小
? ? ? ?缺點:切換是全量的,如果新版本有問題,則對用戶體驗有直接影響,需要雙倍機器資源
灰度發布:舊版本和新版本共存
? ? 將新版本部署到一部分生產環境,讓一部分用戶先試用,如果沒有問題,再逐步擴大范圍,把全部服務都切換到新環境。
? ? ? ? 優點:用戶體驗影響小,灰度發布過程出現問題只影響部分用戶
滾動更新:平滑地將服務更新
3? Deployment滾動發布
[root@master231 deployments]# cat 02-deploy-nginx-strategy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-nginx-strategy
spec:# 定義升級策略strategy:# 指定升級類型,有效值為Recreate和RollingUpdate.# Recreate:# 先刪除所有舊的Pod,再創建新的Pod。# RollingUpdate:# 先刪除部分舊的Pod,滾動更新舊的Pod,逐步使用新的Pod替代舊的Pod。# 默認就是基于滾動更新類型。# type: Recreatetype: RollingUpdate# 滾動更新rollingUpdate:# 在升級過程中,在原有舊的Pod基礎之上啟動的Pod數量。maxSurge: 2# 在升級過程中,指定最大不可用的數量。maxUnavailable: 1#maxSurge: "20%"#maxUnavailable: "10%"replicas: 5selector:matchExpressions:- key: appsvalues: - "v1"- "v2"operator: Intemplate:metadata:labels:apps: v1school: liuxspec:containers:- name: v1# image: harbor.liux.com/liux-apps/apps:v1image: harbor.liux.com/liux-apps/apps:v2imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:name: deploy-strategy
spec:type: NodePortselector:apps: v1school: liuxports:- port: 8888targetPort: 80nodePort: 30000
[root@master231 deployments]#
升級過程
-------------> 第一波
舊的pod: 4
新的pod: 3 -------------> 第二波
舊的pod: 1
新的新的: 3 + 2[root@master231 deployments]# kubectl apply -f 02-deploy-nginx-strategy.yaml
deployment.apps/deploy-nginx configured
service/deploy-strategy unchanged
[root@master231 deployments]# kubectl get po,svc -o wide
#切換版本
[root@master231 deployments]# vim 02-deploy-nginx-strategy.yaml #image: harbor.liux.com/liux-apps/apps:v1image: harbor.liux.com/liux-apps/apps:v2
4.Deloyment藍綠發布
4.1?部署藍環境
[root@master231 blue-green]# cat 01-blue.yaml
kind: Deployment
apiVersion: apps/v1
metadata:name: liux-blue
spec:replicas: 3selector:matchLabels:app: bluetemplate:metadata:labels:app: bluespec:containers:- name: v1image: harbor.liux.com/liux-apps/apps:v1---kind: Service
apiVersion: v1
metadata:name: liux-app-svc
spec:type: NodePortports:- port: 80targetPort: 80nodePort: 30080selector:app: blue
[root@master231 blue-green]#
[root@master231 blue-green]# kubectl apply -f 01-blue.yaml
deployment.apps/liux-blue created
service/liux-app-svc created
[root@master231 blue-green]#
#測試訪問
[root@master231 blue-green]# while true ; do sleep 0.5;curl 10.0.0.233:30080; done
4.2 部署綠環境
[root@master231 blue-green]# cat 02-green.yaml
kind: Deployment
apiVersion: apps/v1
metadata:name: liux-green
spec:replicas: 3selector:matchLabels:app: greentemplate:metadata:labels:app: greenspec:containers:- name: mywebimage: harbor.liux.com/liux-apps/apps:v2
[root@master231 blue-green]#
[root@master231 blue-green]# kubectl apply -f 02-green.yaml
deployment.apps/liux-green created
4.4 切換svc的標簽
[root@master231 blue-green]# cat 03-switch-svc-selector.yaml
kind: Service
apiVersion: v1
metadata:name: liux-app-svc
spec:type: NodePortports:- port: 80targetPort: 80nodePort: 30080selector:# app: blueapp: green
[root@master231 blue-green]#
[root@master231 blue-green]# kubectl apply -f 03-switch-svc-selector.yaml
service/liux-app-svc configured
5.Deployment灰度發布
5.1?部署舊版本
?先將副本數設置為3,隨著新版本的創建,將副本逐漸調低到0
[root@master231 canary-huidu]# cat 01-old.yaml
kind: Deployment
apiVersion: apps/v1
metadata:name: liux-old
spec:replicas: 3selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- name: mywebimage: harbor.liux.com/liux-apps/apps:v1
---
kind: Service
apiVersion: v1
metadata:name: liux-web-svc
spec:type: NodePortports:- port: 80targetPort: 80nodePort: 30080selector:app: web
[root@master231 canary-huidu]#
[root@master231 canary-huidu]# kubectl apply -f 01-old.yaml
deployment.apps/liux-old created
service/liux-web-svc created
5.2?部署新版本
? 先將副本數設置為1,隨著新版本的穩定,將副本逐漸調高到3
[root@master231 canary-huidu]# cat 02-new.yaml
kind: Deployment
apiVersion: apps/v1
metadata:name: liux-new
spec:replicas: 1selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- name: mywebimage: harbor.liux.com/liux-apps/apps:v2
[root@master231 canary-huidu]#
[root@master231 canary-huidu]#
[root@master231 canary-huidu]# kubectl apply -f 02-new.yaml
deployment.apps/liux-new created
5.3?修改副本數量以及測試結果
? 將舊的副本數量手動修改從3-0,與此同時,將新的副本數量從1-3
[root@master231 canary-huidu]# kubectl edit deploy liux-old
deployment.apps/liux-old edited
[root@master231 canary-huidu]# kubectl edit deploy liux-new
deployment.apps/liux-new edited#測試訪問
[root@master231 ~]# while true ; do sleep 0.5;curl 10.0.0.233:30080; done
三、service
1.概述
? ? ? ? service 用于服務發現和負載均衡。基于labels標簽關聯后端pod列表,以實現后端節點得動態發現,從而管理endpoints資源;負載均衡,底層借助于kube-proxy組件實現,基于iptables或者ipvs將用戶請求轉發給不同的Pod以均衡流量。
? ? ? ?Service配置Selector標簽, Endpoints Controller(controller manager)會自動創建對應的endpoint對象,否則.不會生成endpoint對象。
2.service類型
- ClusterIP(默認):集群內部訪問,自動分配一個僅 Cluster 內部可以訪問的虛擬 IP;
- NodePort:通過節點IP和端口暴露服務,在ClusterIP基礎上為service在所有worker節點綁定一個端口,通過nodeport端口來訪問服務;
- LoadBalancer:集成云廠商的負載均衡器(如AWS ELB);
- ExternalName:映射到外部DNS。用于將K8S集群外部的服務映射至K8S集群內部訪問,讓集群內部的Pod能夠通過固定的service名稱訪問集群外部的服務。
3.service示例
[root@master-1 nfs]# vim nginx-demo.yaml
apiVersion: v1
kind: Service
metadata:labels:app: nginx-demoname: nginx-demo
spec:# 指定svc的類型為NodePort,也就是在默認的ClusterIP基礎之上多監聽所有worker節點的端口而已。type: NodePort# 配置端口映射ports:- nodePort: 30698# 指定Service服務本身的端口號port: 88protocol: TCP# 后端Pod提供服務的端口號targetPort: 80# 基于標簽選擇器關聯Podselector:app: nginx-demo[root@master-1 nfs]# kubectl apply -f nginx-demo.yaml
[root@master-1 nfs]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 16d
nginx-demo NodePort 10.0.0.187 <none> 88:30698/TCP 2d
[root@master-1 nfs]# kubectl get endpoints
NAME ENDPOINTS AGE
nginx-demo 172.17.1.3:80,172.17.77.11:80 2d1h[root@master-1 nfs]# kubectl describe svc nginx-demo
Name: nginx-demo
Namespace: default
Labels: app=nginx-demo
Annotations: <none>
Selector: app=nginx-demo
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.0.0.187
IPs: 10.0.0.187
Port: <unset> 88/TCP
TargetPort: 80/TCP
NodePort: <unset> 30698/TCP
Endpoints: 172.17.1.3:80,172.17.77.11:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>#訪問
http://192.168.91.22:30698
4.endpoints
? ? ? ?Endpoint是Kubernetes集群中的一個資源對象,存儲在etcd中,用來記錄一個Service對應的所有pod的訪問地址.
? ? ? ?Service配置Selector, 創建service時Endpoints Controller(controller manager)會自動創建對應的endpoint對象,否則.不會生成endpoint對象.
#查看endpoints
[root@master-1 nfs]# kubectl get endpoints
NAME ENDPOINTS AGE
fuseim.pri-ifs <none> 13d
kubernetes 192.168.91.18:6443,192.168.91.19:6443,192.168.91.20:6443 16d
nginx-demo 172.17.1.3:80,172.17.77.11:80 2d1h
#查看etcd數據
[root@master-1 nfs]# export ETCDCTL_API=3
[root@master-1 nfs]# export ETCD_ENDPOINTS=http://192.168.91.19:2390
[root@master-1 nfs]# etcdctl --endpoints=${ETCD_ENDPOINTS} get / --prefix --keys-only | grep 'endpoints/default/nginx-demo'
/registry/services/endpoints/default/nginx-demo
四、Ingress
1.概念
? ? ? ????Ingress是k8s中管理外部流量的核心組件,通過靈活的路由規則和豐富的控制器生態滿足多樣化需求。
? ? ? ? k8s使用ingress和ingress controller兩者結合實現了完整的ingress負載均衡器。 負載分發時,ingress controller基于ingress規則將請求轉發到service對應的endpoint上,用于將不同URL的訪問請求轉發到后端不同的service,以實現http層的業務路由機制。
? ? ? ? 全過程:ingress controller-->ingress規則-->services-->endpoints(pod)
2.示例 編寫ingress規則
訪問nginx.liux.com,將會代理到svc中名稱nginx.liux.com端口88上去
[root@master-1 ingress]# cat nginx-route-https.yaml
#注意命名空間 namespace與要代理的服務需要在同一個名稱空間
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:name: nginx-routenamespace: kube-system
spec:entryPoints:- webroutes:- match: Host(`nginx.liux.com`)kind: Ruleservices:- name: nginx-demoport: 88
3.Ingress與service的區別
? ? ? ?在 K8s 中,Ingress 和 Service 都是用于管理網絡流量的核心組件,但它們的職責和使用場景有顯著區別。
- Service?是基礎網絡抽象,確保 Pod 的可訪問性。
- Ingress 是高級流量網關,專注于 HTTP 路由和集中管理。
- 兩者通常結合使用:Ingress 處理外部請求的路由,Service 負責內部流量的分發。
特性 | Service | Ingress |
---|---|---|
層級 | L4(TCP/UDP) | L7(HTTP/HTTPS |
核心功能 | 服務發現、基礎負載均衡 | 高級路由、SSL 終止、流量管理 |
外部暴露方式 | NodePort、LoadBalancer | 通過 Ingress Controller + 規則 |
路由規則 | 僅 IP/端口 | 域名、路徑、請求頭等 |
資源成本 | 每個 LoadBalancer 獨立實例 | 單一入口點管理多個服務 |
依賴組件 | 無需額外組件 | 需要 Ingress Controller |
示例:一個 Web 應用服務包含frontend-service(前端)和backend-service(后端 API),可進行如下配置:
配置方式:
- Service:為 frontend-service 和 backend-service 創建 ClusterIP 類型的 Service,供集群內訪問。
- Ingress:定義規則將 www.example.com/ 路由到 frontend-service,將 www.example.com/api 路由到 backend-service,并啟用 HTTPS。
? ? ? ?這樣外部用戶通過統一的域名訪問,而 Ingress 根據路徑將請求分發到不同的 Service,再由 Service 負載均衡到具體的 Pod。
五.?ConfigMap 和 Secret
? ? ? ?ConfigMap 和 Secret 都是用于管理應用配置的核心資源,但它們的用途和安全性有顯著區別。
1.?ConfigMap
作用:
- 存儲 非敏感 的配置數據(如環境變量、配置文件、命令行參數等
- 將配置與容器鏡像解耦,便于應用配置的靈活管理
數據格式:
- 數據以 明文 形式存儲(如鍵值對、JSON、YAML 或純文本文件)
典型場景:
- 存儲應用的配置文件(如 nginx.conf、application.properties)。
- 定義環境變量(如 LOG_LEVEL=debug)。
- 共享配置給多個 Pod 或多個容器。
安全性:
- 不加密,數據對集群內用戶可見,不適合存儲敏感信息。
使用方式:
- 通過環境變量注入容器。
- 掛載為卷(Volume)到 Pod 的文件系統中。
示例:
#編寫cm資源
[root@master231 cm]# cat 02-cm-games.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: nginx-conf
# 指定cm的數據
data:games.conf: |server {listen 0.0.0.0:99;root /usr/local/nginx/html/bird/;server_name game01.liux.com;}#編寫pod資源清單(在此引用cm資源)
[root@master231 pod]# vim 16-pods-volumes-configMap-games.yaml
apiVersion: v1
kind: Pod
metadata:name: liux-games-cm-008
spec:nodeName: worker233# hostNetwork: truevolumes:- name: data01# 指定存儲卷類型是configMapconfigMap:# 指定configMap的名稱name: nginx-conf# 引用configMap中的某個key,若不指定,則引用configMap資源的所有key。#items:# 指定configMap的key#- key: student.info# 暫時理解為在容器掛載點的文件名稱。#path: banzhan.infocontainers:- name: gamesimage: harbor.liux.com/liux-games/games:v0.5volumeMounts:- name: data01#mountPath: /liux-linux86mountPath: /etc/nginx/conf.d/
2.Secret
作用:
- 存儲 敏感信息(如密碼、API 密鑰、TLS 證書、SSH 密鑰等)。
- 提供一定程度的安全保護(非完全加密,需結合其他機制增強安全性)。
數據格式:
- 數據以 Base64 編碼 形式存儲(非加密,僅防意外泄露)。
- 支持 stringData 字段直接寫入明文(自動轉換為 Base64)。
典型場景:
- 存儲數據庫密碼(如 mysql-password)。
- 存儲 TLS 證書(如 tls.crt 和 tls.key)。
- 容器鏡像倉庫的認證信息(如 Docker harbor 憑據)。
安全性:
- Base64 編碼僅防止明文暴露,仍需配合以下措施
- 啟用 Kubernetes 的 Secret 加密機制(如使用 KMS、Vault)。
- 限制集群內 RBAC 權限(避免未授權訪問)。
使用方式:
- 通過環境變量注入容器(不推薦,可能被日志記錄)。
- 掛載為卷到 Pod 的文件系統中(更安全)。
示例一創建:
#1.聲明式創建
[root@master231 secrets]# echo admin |base64
YWRtaW4K
[root@master231 secrets]# echo 12366 |base64
MTIzNjYK
[root@master231 secrets]# vim 01-secret-userinfo.yaml apiVersion: v1
kind: Secret
metadata:name: my-secrets-01
data:# 對于Secret的值進行base64編碼,當Pod的容器使用secret時會自動對數據進行解碼username: YWRtaW4Kpassword: MTIzNjYK
[root@master231 secrets]# kubectl apply -f 01-secret-userinfo.yaml
secret/my-secrets-01 created
[root@master231 secrets]# kubectl get secrets
NAME TYPE DATA AGE
my-secrets-01 Opaque 2 82s#2. 響應式創建# - 基于命令行key=value的方式創建
[root@master231 secrets]# kubectl create secret generic my-secrets-02 --from-literal=username='admin' --from-literal=password='12366'# - 基于命令行讀取文件的方式創建
[root@master231 secrets]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q
[root@master231 secrets]# kubectl create secret generic my-secrets-03 --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub #響應式創建harbor的認證信息
[root@master231 secrets]# kubectl create secret docker-registry liux-harbor --docker-username=admin --docker-password=12366 --docker-email=admin@liux.com --docker-server=harbor.liux.com
示例二引用:
#3.在pod中引用 基于存儲卷、環境變量的方式掛載[root@master231 pod]# cat 31-pods-secrets-env-volumes.yaml
apiVersion: v1
kind: Pod
metadata:name: linux86-web-secrets-env-cm-001
spec:volumes:- name: data01# 指定存儲卷類型為secretsecret:# 指定secret的名稱secretName: my-secrets-01- name: data02secret:secretName: my-secrets-01items:- key: usernamepath: username.info- key: passwordpath: password.txtcontainers:- name: webimage: harbor.liux.com/liux-web/nginx:1.25.1-alpine#基于存儲卷的方式掛載volumeMounts:- name: data01mountPath: /liux-linux86-secrets- name: data02mountPath: /liux-linux86-secrets-2#基于環境變量的方式掛載env:- name: liux_USERNAMEvalueFrom:# 值引用自某個secretsecretKeyRef:# 指定secret的名稱name: my-secrets-01# 指定引用secret對應的keykey: username- name: liux_SSH_PRIVATEKEYvalueFrom:secretKeyRef:name: my-secrets-03key: ssh-privatekey
[root@master231 pod]#
[root@master231 pod]# kubectl apply -f 31-pods-secrets-env-volumes.yaml
pod/linux86-web-secrets-env-cm-001 created
[root@master231 pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
linux86-web-secrets-env-cm-001 1/1 Running 0 8s
[root@master231 pod]# kubectl exec -it linux86-web-secrets-env-cm-001 -- env#在pod中引用harbor登錄信息 注意,請確保你創建的用戶必須在harbor中對相應的項目有訪問權限!
[root@master231 pod]# cat 32-pods-harbor-secrets.yaml
apiVersion: v1
kind: Pod
metadata:name: linux86-secrets-harbor-001
spec:# 指定harbor的secret認證信息,可以指定多個。imagePullSecrets:- name: harbor-liuxing# - name: liux-harborcontainers:- name: webimage: harbor.liux.com/liux-apps/apps:v1# 指定鏡像的拉取策略,若不指定,當tag為latest時,默認是Always,當tag非latest時,則默認策略為IfNotPresentimagePullPolicy: Always# imagePullPolicy: IfNotPresent
3.總結
特性 | ConfigMap | Secret |
---|---|---|
數據類型 | 非敏感配置(明文) | 敏感信息(Base64 編碼) |
安全性 | 無加密,明文存儲 | Base64 編碼(非加密),需額外安全措施 |
典型用途 | 配置文件、環境變量、命令行參數 | 密碼、密鑰、證書 |
存儲限制 | 無大小限制 | 每個 Secret 最大 1MiB |
更新與熱加載 | 支持更新,掛載為卷時可自動同步 | 同 ConfigMap,但需注意敏感數據更新策略 |