K8S初步實踐 – 簡單本地集群部署
代碼地址
K8S原理介紹
Kubernetes(K8S)是一個可以幫助我們管理微服務(microservices)的系統,他可以自動化地部署及管理多臺機器上的多個容器(容器),更進一步而言,Kubernetes想解決的問題是:“手動部署多個容器到多臺機器上并監測管理這些容器的狀態非常麻煩,”而Kubernetes要提供的解法:提供一個平臺以高層結構的抽象化去自動化操作與管理容器們,
K8S能做到
- 同時部署多個容器到多臺機器上(部署)
- 服務的乘載量有變化時,可以對容器做自動擴展(縮放)
- 管理多個容器的狀態,自動檢測并重啟故障的容器(管理)
K8S的基本組件
K8S架構圖

K8S的核心組件
- etcd保存了整個集群的狀態;
- apiserver提供了資源操作的唯一入口,并提供認證、授權、訪問控制、API注冊和發現等機制;
- controller manager負責維護集群的狀態,比如故障檢測、自動擴展、滾動更新等;
- scheduler負責資源的調度,按照預定的調度策略將Pod調度到相應的機器上;
- kubelet負責維護容器的生命周期,同時也負責Volume(CVI)和網路(CNI)的管理;
- Container runtime負責鏡像管理以及Pod和容器的真正運行(CRI);
- kube-proxy負責為Service提供cluster內部的服務發現和負載均衡;
官網全部組件介紹
Pod
Kubernetes運作的最小單位,一個Pod對應到一個應用服務(Application),表示一個Pod可能會對應到一個API Server,
- 每個Pod都有一個身分證,也就是屬于這個Pod的yaml檔
- 一個Pod里面可以有一個或者多個Container,但一般情況一個Pod最好只有一個Container
- 同一個Pod中的Containers共享相同資源及網路,彼此透過local port number溝通
- Pod,是 Kubernetes 專案的原子調度單位,
官方介紹
Node
K8s集群中的計算能力由Node提供,最初Node稱為服務節點Minion,后來改名為Node,K8s集群中的Node也就等同于Mesos集群中的Slave節點,是所有Pod運行所在的作業主機,可以是物理機也可以是虛擬機,不論是物理機還是虛擬機,作業主機的統一特征是上面要運行kubelet管理節點上運行的容器,
K8S 集群的簡單部署準備
- 系統:mac os
- docker: 19.03.13
- docker image
- 實作了輸出hello world
- 實作介面/panic 非正常終止
- 實作/version 查看當前api 版本
kubectl 安裝
mac 通過brew安裝
brew install kubectl
or
brew install kubernetes-cli
驗證是否安裝成功
kubectl version --client
其他的安裝方式
minikube 安裝
這里我們安裝阿里云的版本
curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.13.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
驗證
●? minikube version
minikube version: v1.13.0
commit: 23aa1eb200a03ae5883dd9d453d4daf3e0f59668
K8S 簡單部署(借助minikube)
啟動一個單節點的minikube
minikube start --cpus=2 --memory=2048mb --registry-mirror=https://t65rjofu.mirror.aliyuncs.com --driver=virtualbox
這里指定了cpu和記憶體資源
●? minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
●? kubectl get no
NAME STATUS ROLES AGE VERSION
minikube Ready master 106s v1.19.0
pod的yaml檔案
apiVersion: v1
kind: Pod
metadata:
name: docker-demo
spec:
containers:
- name: docker-demo
image: sundacheng/docker_demo:latest
執行部署
●? kubectl apply -f .
pod/docker-demo created
●? kubectl get all
NAME READY STATUS RESTARTS AGE
pod/docker-demo 0/1 ContainerCreating 0 17s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m46s
現在我們沒有將服務暴露出來
所以我們要執行
●? kubectl port-forward docker-demo 3000:3000
Forwarding from 127.0.0.1:3000 -> 3000
Forwarding from [::1]:3000 -> 3000
●? curl 127.0.0.1:3000
hello docker%
部署一個service
剛剛我們部署的pod,通過pord-forward暴露對應埠到宿主機,這種只能是用來測驗,我們可以通過k8s的反向代理來實作一個service.
在這之前簡單介紹下Label和Label selector
Label
Label是Kubernetes系列中另外一個核心概念,是一組系結到K8s資源物件上的key/value對,同一個物件的labels屬性的key必須唯一,label可以附加到各種資源物件上,如Node,Pod,Service,RC等
通過給指定的資源物件捆綁一個或多個不用的label來實作多維度的資源分組管理功能,以便于靈活,方便地進行資源分配,調度,配置,部署等管理作業,
Label selector(標簽選擇器)
Label selector是Kubernetes核心的分組機制,通過label selector客戶端/用戶能夠識別一組有共同特征或屬性的資源物件,
Label selector的使用場景
1.kube-controller行程通過資源物件RC上定義的Label Selector來篩選要監控的Pod副本的數量,從而實作Pod副本的數量始終符合預期設定的全自動控制流程
2.kupe-proxy行程通過Service的Label Selector來選擇對應的Pod,自動建立器每個Service到對應Pod的請求轉發路由表,從而實作Service的智能負載均衡機制
3.通過對某些Node定義特定的Label,并且在Pod定義檔案中使用NodeSelector這種標簽調度策略,Kube-scheduler行程可以實作Pod定向調度的特性
Laber 和Label selector 官方檔案
發布服務的型別
-
ClusterIP:通過集群的內部 IP 暴露服務,選擇該值,服務只能夠在集群內部可以訪問,這也是默認的 ServiceType,
-
NodePort:通過每個 Node 上的 IP 和靜態埠(NodePort)暴露服務, NodePort 服務會路由到 ClusterIP 服務,這個 ClusterIP 服務會自動創建, 通過請求 :,可以從集群的外部訪問一個 NodePort 服務,
-
LoadBalancer:使用云提供商的負載局衡器,可以向外部暴露服務, 外部的負載均衡器可以路由到 NodePort 服務和 ClusterIP 服務,
-
ExternalName:通過回傳 CNAME 和它的值,可以將服務映射到 externalName 欄位的內容(例如, foo.bar.example.com), 沒有任何型別代理被創建,
部署svc
pod的yml
apiVersion: v1
kind: Pod
metadata:
name: docker-demo
labels:
app: docker-demo #給 pod加上標簽
spec:
containers:
- name: docker-demo
image: sundacheng/docker_demo:v1.0.1
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
svc的yml
apiVersion: v1
kind: Service
metadata:
name: docker-demo
spec:
ports:
- name: http
port: 3000
targetPort: 3000
nodePort: 31080 # 指定發布服務型別是nodePort 并且指定對外(宿主機)埠號
selector:
app: docker-demo #Label selector
type: NodePort
執行部署和驗證
●? kubectl apply -f .
pod/docker-demo created
service/docker-demo created
●? kubectl get all
NAME READY STATUS RESTARTS AGE
pod/docker-demo 0/1 ContainerCreating 0 43s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/docker-demo NodePort 10.110.72.67 <none> 3000:31080/TCP 43s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2m52s
●? minikube service docker-demo --url
http://192.168.99.129:31080
●? curl http://192.168.99.129:31080
Hello World!%
可以通過svc進行藍綠部署
well,我們現在有一個版本號是1.0.1的pod,如果我們要升級或者降級,可以通過svc實作藍綠部署
首先pod的image需要更改到要部署的image,并加上新的lable代表版本號
v1.0.0.yml
apiVersion: v1
kind: Pod
metadata:
name: docker-demo-v1.0.0
labels:
app: docker-demo
version: v1.0.0
spec:
containers:
- name: docker-demo
image: sundacheng/docker_demo:v1.0.0
v1.0.1把對應引數改了就行
svc的yml
apiVersion: v1
kind: Service
metadata:
name: docker-demo
spec:
ports:
- name: http
port: 3000
targetPort: 3000
nodePort: 31080
selector:
app: docker-demo
version: v1.0.1
type: NodePort
執行驗證
●? ls
demo-pod-v1.0.0.yml demo-pod-v1.0.1.yml demo-service.yml
●? kubectl apply -f .
pod/docker-demo-v1.0.0 created
pod/docker-demo-v1.0.1 created
service/docker-demo created
●? kubectl get all
NAME READY STATUS RESTARTS AGE
pod/docker-demo-v1.0.0 1/1 Running 0 5m19s
pod/docker-demo-v1.0.1 1/1 Running 0 5m19s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/docker-demo NodePort 10.96.92.104 <none> 3000:31080/TCP 5m19s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 43m
●? minikube service docker-demo --url
http://192.168.99.129:31080
●? curl http://192.168.99.129:31080/version
1.0.1%
# 修改svc的selector 指向1.0.0
●? kubectl apply -f .
pod/docker-demo-v1.0.0 unchanged
pod/docker-demo-v1.0.1 unchanged
service/docker-demo configured
●? curl http://192.168.99.129:31080/version
1.0.0%
svc的rs集群部署
上面講了單節點單個pod的部署,現在講下多節點,
多個node節點需要虛擬機,通過token加入,minikube幫我們做了這點,只需要在最開始minikube start后面加上引數--node=3
minikube start --cpus=2 --memory=2048mb --registry-mirror=https://t65rjofu.mirror.aliyuncs.com --driver=virtualbox --nodes=3
同時pod的yml檔案也要做修改
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: docker-demo
spec:
replicas: 3 #指定rs數量
selector:
matchLabels:
app: docker-demo
template: #定義每個pod的類容
metadata:
labels:
app: docker-demo
spec:
containers:
- name: docker-demo
image: sundacheng/docker_demo:v1.0.1
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
執行部署驗證
●? kubectl get no
NAME STATUS ROLES AGE VERSION
minikube Ready master 8m28s v1.19.0
minikube-m02 Ready <none> 7m33s v1.19.0
minikube-m03 Ready <none> 6m39s v1.19.0
#查看node節點
●? kubectl get all
NAME READY STATUS RESTARTS AGE
pod/docker-demo-5mcx4 1/1 Running 0 6m32s
pod/docker-demo-qgt9r 1/1 Running 0 6m32s
pod/docker-demo-rgdzq 1/1 Running 0 6m32s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/docker-demo NodePort 10.103.56.181 <none> 3000:31080/TCP 6m32s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15m
NAME DESIRED CURRENT READY AGE
replicaset.apps/docker-demo 3 3 3 6m32s
#部署成功
●? kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
docker-demo-5mcx4 1/1 Running 0 7m10s 172.17.0.2 minikube-m03 <none> <none>
docker-demo-qgt9r 1/1 Running 0 7m10s 172.17.0.2 minikube-m02 <none> <none>
docker-demo-rgdzq 1/1 Running 0 7m10s 172.17.0.3 minikube <none> <none>
#查看pod和node的系結關系
deployment 部署
K8S提供了一種更加簡單的更新RC和Pod的機制,叫做Deployment,通過在Deployment中描述你所期望的集群狀態,Deployment Controller會將現在的集群狀態在一個可控的速度下逐步更新成你所期望的集群狀態,Deployment主要職責同樣是為了保證pod的數量和健康,90%的功能與Replication Controller完全一樣,可以看做新一代的Replication Controller,
功能:
- 事件和狀態查看:可以查看Deployment的升級詳細進度和狀態,
- 回滾:當升級pod鏡像或者相關引數的時候發現問題,可以使用回滾操作回滾到上一個穩定的版本或者指定的版本,
- 版本記錄: 每一次對Deployment的操作,都能保存下來,給予后續可能的回滾使用,
- 暫停和啟動:對于每一次升級,都能夠隨時暫停和啟動,
- 多種升級方案:Recreate----洗掉所有已存在的pod,重新創建新的; RollingUpdate----滾動升級,逐步替換的策略,同時滾動升級時,支持更多的附加引數,例如設定最大不可用pod數量,最小升級間隔時間等等,
#創建命令:kubectl create -f deployment.yaml --record
#使用rollout history命令,查看Deployment的歷史資訊:kubectl rollout history deployment docker-demo
#使用rollout undo回滾到上一版本: kubectl rollout undo deployment docker-demo
#使用–to-revision可以回滾到指定版本: kubectl rollout undo deployment docker-deployment --to-revision=2
config map
ConfigMap 允許你將組態檔與鏡像檔案分離,以使容器化的應用程式具有可移植性, 本頁提供了一系列使用示例,這些示例演示了如何創建 ConfigMap 以及配置 Pod 使用存盤在 ConfigMap 中的資料,
config map yml
apiVersion: v1
kind: ConfigMap
metadata:
name: docker-config-v2
data:
SPRING_PROFILES_ACTIVE: mysql
DATASOURCE_URL: jdbc:mysql://mysql/demo/update
DATASOURCE_USERNAME: root
DATASOURCE_PASSWORD: k8s_test
DATASOURCE_INIT_MODE: always
TEST_CONFIG: test_config_v2
對應pod yml修改
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-demo
spec:
selector:
matchLabels:
app: docker-demo
minReadySeconds: 06
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 #
maxSurge: 2 #升級程序中可以比預設的 pod 的數量多出的個數,默認值是25%
replicas: 3
template:
metadata:
labels:
app: docker-demo
spec:
containers:
- name: docker-demo
image: sundacheng/docker_demo:v1.0.1
envFrom: # 指定讀取config
- configMapRef:
name: docker-config-v2
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
我們更新config map配置后,需要我們重啟deployment才能重新加載配置,
重啟deployment
kubectl replace --force -f demo-deployment.yml
水平擴展HPA
水平擴展HPA可以參照阿里云的文章,
【從入門到放棄-Kubernetes】Kubernetes進階-pod水平自動伸縮(hpa)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/210399.html
標籤:python
上一篇:使用HAProxy+Nginx搭建web集群 ———— Keepalived實作高可用負載均衡
下一篇:速學-分布式系統與一致性協議
