k8s入門你至少需要會哪些


前言

相信很多公司都有集成發布pass系統,底層大多數依賴於k8s來進行服務的發布部署/回滾等功能。
對於很多業務開發者都是不可見的,在感嘆這個東西真好用的同時,想着探一探這背后的原理。

真正的入門還是得自己親手跑起來!

今天這篇k8s入門我整理了必會的幾個k8s知識點

  • docker的使用,鏡像的創建和發布(我當你已經會了哈)
  • k8s開發環境搭建
  • Deployment的使用
  • Service的使用
  • ConfigMap的使用

學習環境搭建

首先k8s學習的話是建議用minikube搭建,這里系統我用的ubuntu20.04.2.0LTS

image

我這里用的是vmware虛擬機,
如果FQ不順利的話請加我微信獲取已經裝好環境的虛擬機(節省你時間不香嗎),前提你的機器得是32G內存或以上

image

假設你自己裝了,或者你用了我的vmware虛擬機,或者你用docker Desktop裝的k8s,那么啟動后

敲命令來啟動minikube:

minikube start

image

耐心等待完成后使用 minikube status 查看狀態是否是Running:

image

然后我們要啟動k8s控制面板-dashbord服務,下面的命令里 —url 的意思是啟動后,打印dashbord的url。不帶的話會啟動你本機瀏覽器打開。

minikube dashboard --url

image

k8s的控制面板默認的是本機(localhost)才能打開,所以需要使用k8s的proxy功能,到虛擬機的terminal窗口敲入以下命令:


kubectl proxy --port=8001 --address=0.0.0.0 --accept-hosts='^.*'

image

由於是虛擬機環境,只能是虛擬機所在的機器才能打開 需要做虛擬機端口映射,
本虛擬機的請忽略此步驟!

image

image

做了本機端口到虛擬機的端口映射之后,

打開你本機瀏覽器直接訪問虛擬機的k8s的控制面板

注意我上面用的k8s proxy是8001端口,url如下:

http://<本機IP>:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/#/service?namespace=default

打開如下圖:

image

寫一個demo應用然后部署到k8s

demo就是一個自帶的的天氣預報的webapi模板。

然后創建成功后 需要更改一處代碼(看注釋):


[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger) {
_logger = logger;
}

[HttpGet]
public IEnumerable<WeatherForecast> Get() {
//這里加下獲取本機ip,因為到時候部署到k8s我們得確認是不是訪問的ip會變化
var feature = HttpContext.Features.Get<IHttpConnectionFeature>();
string LocalIPAddr = feature?.LocalIpAddress?.ToString() ?? "unknow";

var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
//到時候候我們確認這個字段即可
Summary = LocalIPAddr
})
.ToArray();
}
}

然后把這個demo應用創建一個鏡像並推送到dockerhub倉庫,

這里我使用我的開源工具AntDeploy來一鍵推送。

image

這個工具使用教程可以查看我之前寫的

[開源]制作docker鏡像不依賴linux和Docker環境

工具的背后原理可以查看:

Docker鏡像構建原理解析(不裝docker也能構建鏡像)

我把這個demo傳到了dokcerHub鏡像的地址:nainaigu/k8s-demo:1.8

1. Deployment的使用

Deployment的作用是定義及管理多副本應用(即多個副本 Pod)

如果Pod出現故障,對應的服務也會掛掉,所以Kubernetes提供了一個Deployment的概念,
目的是讓Kubernetes去管理一組Pod的副本,也就是副本集,
這樣就能夠保證一定數量的副本一直可用,不會因為某一個Pod掛掉導致整個服務掛掉。

編寫Deployment的yml文件


apiVersion: apps/v1 // 指定版本,支持的版本可以通過kubectl api-versions查詢
kind: Deployment //固定 指定類型,這一次我們要創建一個Deployment
metadata: #元數據
name: k8s-demo //delpoyment的名稱,必須在deployment中保持唯一
labels:
name: k8s-demo //反正所有標簽都一個名字
spec: //deployment的詳細內容
replicas: 2 //容器2個副本pod
selector: //選擇器
matchLabels:
name: k8s-demo //選擇label中的name=k8s-demo的
template:
metadata:
labels:
name: k8s-demo //指定一個label名為name,值為k8s-demo,對應上面的selector
spec:
containers:
- name: k8s-demo //容器名
image: nainaigu/k8s-demo:1.8 //鏡像地址
imagePullPolicy: IfNotPresent //如果本地沒有鏡像就去倉庫pull
ports:
- containerPort: 5000 //容器暴露的端口
env: //環境變量
- name: "ASPNETCORE_URLS"
value: "http://0.0.0.0:5000"

上面的配置的意思就是:

  • 從鏡像倉庫拉取你的鏡像
  • 配置你的鏡像啟動的參數,暴露的端口等
  • 給你這個服務起個名字並且打上標簽,執行后會有2個pod(服務實例)

接下來把這個配置保存為k8s-demo.yml 上傳到虛擬機然后敲命令裝配到k8s

//創建
kubectl create -f k8s-demo.yaml

//查看,后面想看某個pod的啟動日志 也需要先找到pod名稱
kubectl get pod -l name=k8s-demo

image

然后在k8s面板上查看

image

2. Service的使用和創建

k8s Service定義了這樣一種抽象: Service是一種可以訪問 Pod邏輯分組的策略, Service通常是通過 Label Selector訪問 Pod組(等下在寫service的yml文件就能看出來了)

Service的出現,可以解決每次Deployment的時候ip會換的問題

不過Service只支持4層的負載均衡,不支持7層(k8s是用Ingress來支持7層)。

當Pod宕機后重新生成時,其IP等狀態信息可能會變動,
Service會根據Pod的Label對這些狀態信息進行監控和變更,保證上游服務不受Pod的變動而影響

Service在 K8s中有常見的以下幾種類型:

  • ClusterIp <只能是集群內部訪問,可以通過proxy讓外部訪問>
  • NodePort <nodeport來暴露服務讓外部訪問>
  • LoadBalancer <生產環境一般都是使用LoadBalancer的方式>

apiVersion: v1
kind: Service
metadata:
name: k8s-demo
spec:
selector: //篩選pod。上面創建Deployment的時候指定了
name: k8s-demo
type: ClusterIP //只能k8s集群內部訪問,外部網絡不能夠訪問到
ports:
- protocol: TCP
port: 5000 //k8s集群內部通過 5000 端口來訪問 下面的
targetPort: 5000 //容器暴露端口,與Dockerfile暴露端口保持一致

上面的Service配置表示:

  • 創建了一個名叫k8s-demo的Service
  • 用來訪問上面我們Deployment創建的一組name=k8s-demo的Pods
  • 不管你Deployment后面是重新發布還是擴容還是縮容,不管怎么變化,只要通過Service暴露的端口就能負載均衡的訪問到那一組 Pods
  • 我們設置的類型是ClusterIP,默認是k8s集群內部可訪問,但是也可以通過k8s的proxy功能來訪問

如果是NodePort(可以集群外訪問)的話要需要按照如下規則來配置


apiVersion: v1
kind: Service
metadata:
name: k8s-demo
spec:
selector: //篩選pod。上面創建Deployment的時候指定了
name: k8s-demo
type: NodePort //配置為NodePort,外部可以訪問,要定義下面的nodePort參數
ports:
- protocol: TCP
port: 5000 //k8s集群內部通過 5000 端口來訪問 下面的
targetPort: 5000 //容器暴露端口,與Dockerfile暴露端口保持一致
nodePort: 30001 // NodePort,外部訪問的端口來訪問上面的targetPort

總結這2種的區別就是:

集群內 serviceip:容器端口。 集群外: 宿主機IP:nodePort端口

我們按照第一種方式(type: ClusterIP)測試

image

查看下service的ip:10.105.108.92

image

由於是集群內部才能訪問,所以先用下面的命令進入minikube搭建的k8s集群內部環境


minikube ssh

curl http://10.105.108.92:5000/WeatherForecast

image

訪問服務成功!!

在外部網絡可以使用k8s的proxy來訪問


http://10.32.104.164:8001/api/v1/namespaces/default/services/k8s-demo:5000/proxy/WeatherForecast

注意通過proxy訪問的url拼接的規范:

  • k8s-demo:5000 代表你創建的service的名稱和端口
  • /WeatherForecast 代表你服務暴露的接口

image

ConfigMap的使用

ConfigMap 就是為了讓鏡像 和 配置文件解耦。好比一個動態的數據源,你創建后可以在
創建Deployment的時候指定用它。然后你想要動態更新,容器內也能監聽到文件內容更改,進行熱重載!

k8s的另外一個類似的功能叫secret,Secret類似於ConfigMap,是用Base64加密,密文顯示,一般存放敏感數據!

下面創建一個appsettings.json的configMap


apiVersion: v1
kind: ConfigMap
metadata:
name: appsettings
data:
appsettings.json: |-
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Settings": {
"Message": "The configuration is working!"
}
}

然后改下demo應用

image

這里單獨搞了一個Settings的目錄來保存配置文件。

image

然后在api里面讀出來配置的Settings.Message信息

image

這里注意有一個坑 :netcore中的默認的機制是監聽配置文件的lastChangetime,
但是configMap變更后居然不會有任何變化(因為它是符號連接(symbolic link)),所以需要自己寫一個watch來適配,詳細可以看demo中的代碼!

下面來測試下效果:

第一步:把configMap創建到k8s中

第二步:先刪除掉上面創建的Deployment和Service

第三步:在Deployment的配置中用configMap

第四步:重新創建Deployment和Service

以上四步可以一次性搞定,
k8s的yml可以把Deployment和Service和configMap全放在一個yml文件:


apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-demo
labels:
name: k8s-demo
spec:
replicas: 2
selector:
matchLabels:
name: k8s-demo
template:
metadata:
labels:
name: k8s-demo
spec:
containers:
- name: k8s-demo
image: nainaigu/k8s-demo:1.8
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
env:
- name: "ASPNETCORE_URLS"
value: "http://0.0.0.0:5000"
volumeMounts:
- name: appsettings-volume
mountPath: "/publish/Settings" //這里用configMap
volumes:
- name: appsettings-volume
configMap:
name: appsettings //這里用configMap

---

apiVersion: v1
kind: Service
metadata:
name: k8s-demo
spec:
selector:
name: k8s-demo
type: ClusterIP
ports:
- protocol: TCP
port: 5000
targetPort: 5000

---

apiVersion: v1
kind: ConfigMap
metadata:
name: appsettings
data:
appsettings.json: |-
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Settings": {
"Message": "The configuration is working!"
}
}

image

如上圖,一個yml創建了configMap,Service,Deployment。

創建完成后,看下k8s面板:

image

通過proxy訪問下我們的demo服務:

image

由於我們在Deployment指定replicas:2個pod,訪問服務會負載均衡,ip會切換。

配置讀取的configmap信息是默認的 “The configuration is working!”

下面我們動態修改下configMap,來測試下demo應用會不會重新加載!

image

image

然后在來訪問下demo服務

image

確實加載到了新的配置了!

補充一些常用的命令:

查看部署的歷史記錄:

kubectl rollout history deployment.apps/k8s-demo
image

回滾 :kubectl rollout undo
比如回滾到上一個:

kubectl rollout undo deploy/k8s-demo

回滾到指定的版本:

kubectl rollout undo deploy/k8s-demo —to-revision=2 

指定的版本可以通過歷史記錄的Revision字段

擴縮容kubectl scale

kubectl scale deployment k8s-demo —replicas=2

也可以在面板上操作

把2個實例 擴容到3個實例:

image

也可以設置達到某個條件自動擴容:

kubectl autoscale deployment k8s-demo —min=10 —max=20 —cpu-precent=70

代表最低10個實例,一旦cpu超過70% 自動觸發擴容 最大擴容到20個實例

查看Deployment的容器啟動日志 kubectl logs

image

demo應用的源碼:
https://github.com/yuzd/envoytest

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM