Kubernetes(以下簡稱k8s)是自動化容器操作的開源平臺,這些操作包括部署,調度和節點集羣間擴展。如果你曾經用過Docker容器技術部署容器,那麼可以將Docker看成Kubernetes內部使用的低級別組件。Kubernetes不僅僅支持Docker,還支持Rocket,這是另一種容器技術。
爲什麼使用k8s
- 自動化容器的部署和複製
- 隨時擴展或收縮容器規模
- 將容器組織成組,並且提供容器間的負載均衡
- 很容易地升級應用程序容器的新版本
- 提供容器彈性,如果容器失效就替換它,等等...
實際上,使用Kubernetes只需一個部署文件,使用一條命令就可以部署多層容器(前端,後臺等)的完整集羣:
$ kubectl create -f single-config-file.yaml
重要概念
- Cluster: Cluster是計算、存儲和網絡資源的集合,Kubernernets利用這些資源運行各種基於容器的應用。
- Master:Master是Cluster的大腦,它的主要職責是調度,即決定將應用放在哪裏運行。
- Node:Node的職責是運行容器應用。Node由Master管理,Node負責監控並彙報容器的狀態,同時根據Master的要求管理容器的生命週期。
- Pod:Pod是Kubernetes的最小工作單元。每個Pod包含一個多多個容器。
Kubernetes集羣裏有三種IP地址,分別如下:
- Node IP:Node節點的IP地址,即物理網卡的IP地址。
- Pod IP:Pod的IP地址,即docker容器的IP地址,此爲虛擬IP地址。
- Cluster IP:Service的IP地址,此爲虛擬IP地址。
kubectl 常用命令
運行應用
$ sudo kubectl apply -f *.yml
刪除應用
$ sudo kubectl delete -f *.yml
進入k8s管理的一個容器
$ sudo kubectl get pods
$ sudo kubectl exec -it peter-openjdk-5f6d8f8b5d-28rw4 /bin/bash
如一個pod裏有多個容器,用--container or -c 參數。
$ sudo kubectl exec -it peter-producer-consumer -c peter-consumer sh
打標籤:
[admin@k8s-master ~]$ sudo kubectl label node k8s-node2 disktype=kd2
指定部署到某節點
spec:
nodeSelector:
disktype: kd2
刪除標籤
[admin@k8s-master ~]$ sudo kubectl label node k8s-node2 disktype-
配置dns
[admin@k8s-master ~]$ sudo kubectl edit cm -n kube-system coredns
創建命名空間
kubectl get ns
kubectl create ns trade-apps
[admin@k8s-master ~]$ sudo kubectl get nodes
[admin@k8s-master ~]$ sudo kubectl get deployments
[admin@k8s-master ~]$ sudo kubectl get pod --all-namespaces -o wide
[admin@k8s-master ~]$ sudo kubectl get pods -o wide
[admin@k8s-master ~]$ sudo kubectl get services
[admin@k8s-master ~]$ sudo kubectl get events
[admin@k8s-master ~]$ sudo kubectl describe node/deployment/pod/service/event
不同部署類型yml配置
kind的類型有:
- Deployment
- DaemonSet
- Job
- CronJob
- Pod
- Service
Service
type有:
- ClusterIP 只能ClusterIP可以訪問
- NodePort 可以提供外網訪問Service
- LoadBalancer 均衡負載
apiVersion: v1
kind: Service
metadata:
name: peter-nginx-svc
namespace: default
spec:
type: NodePort
ports:
- port: 8080
protocol: TCP
nodePort: 3000
targetPort: 80
selector:
run: peter-nginx
- port ClusterIP監聽的端口
- nodePort NodePort監聽的端口
- targetPort Pod監聽的端口
- 選擇labels爲:peter-nginx的pod
- 將service的8080映射到pod的80端口,使用TCP協議
- pod < service < clusterIp(node機器ip) < 外網訪問
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: peter-openjdk
namespace: default
spec:
replicas: 2
template:
metadata:
name: peter-java-base
labels:
app: peter-java-base
spec:
containers:
- name: peter-java-base
image: reg.was.ink/mcom/javabase-centos-openjdk:1.0
imagePullPolicy: IfNotPresent
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
selector:
matchLabels:
app: peter-java-base
Pod
apiVersion: v1
kind: Pod
metadata:
name: peter-producer-consumer
spec:
containers:
- name: peter-producer
image: busybox
volumeMounts:
- mountPath: /producer_dir
name: shared-volume
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello ; sleep 30000
- name: peter-consumer
image: busybox
volumeMounts:
- mountPath: /consumer_dir
name: shared-volume
args:
- /bin/sh
- -c
- cat /consumer_dir/hello ; sleep 30000
volumes:
- name: shared-volume
emptyDir: {}
模擬生產者消費者,共享存儲
健康檢查
replicas: 2
strategy:
rollingUpdate:
maxSurge: 35%
maxUnavailable: 35%
restartPolicy: Always
readinessProbe:
initialDelaySeconds: 120
periodSeconds: 5
httpGet:
path: /actuator/health
port: 10600
livenessProbe:
initialDelaySeconds: 120
periodSeconds: 5
httpGet:
path: /actuator/health
schema: HTTP
port: 10600
和image參數同級別 schema: HTTP(默認) HTTPS liveness 失敗,容器重啓 readiness失敗,容器不可用,連續3次探測失敗,會從負載均衡中移除 maxSurge: 35% 超過desired的上線 (1+35%) * replicas maxUnavailable: 35%, 不可用佔desired的最大比例 (1+35%) * replicas
k8s 配置文件 詳解
apiVersion: v1 # 【必須】版本號
kind: Pod # 【必選】Pod
metadata: # 【必選-Object】元數據
name: String # 【必選】 Pod的名稱
namespace: String # 【必選】 Pod所屬的命名空間
labels: # 【List】 自定義標籤列表
- name: String
annotations: # 【List】 自定義註解列表
- name: String
spec: # 【必選-Object】 Pod中容器的詳細定義
containers: # 【必選-List】 Pod中容器的詳細定義
- name: String # 【必選】 容器的名稱
image: String # 【必選】 容器的鏡像名稱
imagePullPolicy: [Always | Never | IfNotPresent] # 【String】 每次都嘗試重新拉取鏡像 | 僅使用本地鏡像 | 如果本地有鏡像則使用,沒有則拉取
command: [String] # 【List】 容器的啓動命令列表,如果不指定,則使用鏡像打包時使用的啓動命令
args: [String] # 【List】 容器的啓動命令參數列表
workingDir: String # 容器的工作目錄
volumeMounts: # 【List】 掛載到容器內部的存儲卷配置
- name: String # 引用Pod定義的共享存儲卷的名稱,需使用volumes[]部分定義的共享存儲卷名稱
mountPath: Sting # 存儲卷在容器內mount的絕對路徑,應少於512個字符
readOnly: Boolean # 是否爲只讀模式,默認爲讀寫模式
ports: # 【List】 容器需要暴露的端口號列表
- name: String # 端口的名稱
containerPort: Int # 容器需要監聽的端口號
hostPort: Int # 容器所在主機需要監聽的端口號,默認與containerPort相同。設置hostPort時,同一臺宿主機將無法啓動該容器的第二份副本
protocol: String # 端口協議,支持TCP和UDP,默認值爲TCP
env: # 【List】 容器運行前需設置的環境變量列表
- name: String # 環境變量的名稱
value: String # 環境變量的值
resources: # 【Object】 資源限制和資源請求的設置
limits: # 【Object】 資源限制的設置
cpu: String # CPU限制,單位爲core數,將用於docker run --cpu-shares參數
memory: String # 內存限制,單位可以爲MB,GB等,將用於docker run --memory參數
requests: # 【Object】 資源限制的設置
cpu: String # cpu請求,單位爲core數,容器啓動的初始可用數量
memory: String # 內存請求,單位可以爲MB,GB等,容器啓動的初始可用數量
livenessProbe: # 【Object】 對Pod內各容器健康檢查的設置,當探測無響應幾次之後,系統將自動重啓該容器。可以設置的方法包括:exec、httpGet和tcpSocket。對一個容器只需要設置一種健康檢查的方法
exec: # 【Object】 對Pod內各容器健康檢查的設置,exec方式
command: [String] # exec方式需要指定的命令或者腳本
httpGet: # 【Object】 對Pod內各容器健康檢查的設置,HTTGet方式。需要指定path、port
path: String
port: Number
host: String
scheme: String
httpHeaders:
- name: String
value: String
tcpSocket: # 【Object】 對Pod內各容器健康檢查的設置,tcpSocket方式
port: Number
initialDelaySeconds: Number # 容器啓動完成後首次探測的時間,單位爲s
timeoutSeconds: Number # 對容器健康檢查的探測等待響應的超時時間設置,單位爲s,默認值爲1s。若超過該超時時間設置,則將認爲該容器不健康,會重啓該容器。
periodSeconds: Number # 對容器健康檢查的定期探測時間設置,單位爲s,默認10s探測一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: Boolean
restartPolicy: [Always | Never | OnFailure] # Pod的重啓策略 一旦終止運行,都將重啓 | 終止後kubelet將報告給master,不會重啓 | 只有Pod以非零退出碼終止時,kubelet纔會重啓該容器。如果容器正常終止(退出碼爲0),則不會重啓。
nodeSelector: object # 設置Node的Label,以key:value格式指定,Pod將被調度到具有這些Label的Node上
imagePullSecrets: # 【Object】 pull鏡像時使用的Secret名稱,以name:secretkey格式指定
- name: String
hostNetwork: Boolean # 是否使用主機網絡模式,默認值爲false。設置爲true表示容器使用宿主機網絡,不再使用docker網橋,該Pod將無法在同一臺宿主機上啓動第二個副本
volumes: # 【List】 在該Pod上定義的共享存儲卷列表
- name: String # 共享存儲卷的名稱,volume的類型有很多emptyDir,hostPath,secret,nfs,glusterfs,cephfs,configMap
emptyDir: {} # 【Object】 類型爲emptyDir的存儲卷,表示與Pod同生命週期的一個臨時目錄,其值爲一個空對象:emptyDir: {}
hostPath: # 【Object】 類型爲hostPath的存儲卷,表示掛載Pod所在宿主機的目錄
path: String # Pod所在主機的目錄,將被用於容器中mount的目錄
secret: # 【Object】類型爲secret的存儲卷,表示掛載集羣預定義的secret對象到容器內部
secretName: String
items:
- key: String
path: String
configMap: # 【Object】 類型爲configMap的存儲卷,表示掛載集羣預定義的configMap對象到容器內部
name: String
items:
- key: String
path: String
imagePullPolicy屬性
- Always 總是拉取鏡像
- IfNotPresent 本地有則使用本地鏡像,不拉取
- Never 只使用本地鏡像,從不拉取,即使本地沒有
- 如果省略imagePullPolicy 鏡像tag爲 :latest 策略爲always ,否則 策略爲 IfNotPresent
常見問題
問題1:macbook安裝kubernetes 報:Kubernenes is starting...
1. 先拉去這個
git clone https://github.com/maguowei/k8s-docker-for-mac
2. 執行
./load_images.sh
3. 查看自己電腦裝的Kubernetes的版本號
4. 把2中拉下來的重新打標籤
k8s.gcr.io/kube-proxy v1.15.5 cbd7f21fec99 4 months ago 82.4MB
k8s.gcr.io/kube-apiserver v1.15.5 e534b1952a0d 4 months ago 207MB
k8s.gcr.io/kube-controller-manager v1.15.5 1399a72fa1a9 4 months ago 159MB
k8s.gcr.io/kube-scheduler v1.15.5 fab2dded59dd 4 months ago 81.1MB
$docker tag cbd7f21fec99 k8s.gcr.io/kube-proxy:自己電腦Kubernetes版本號
5. reset > Reset Kubernetes cluster
問題2:pod 報:Back-off restarting failed container
在yml文件中,增加:
command: [ "/bin/bash", "-ce", "tail -f /dev/null" ]
問題3:mount.nfs: Stale file handle
服務端:
vim /etc/exports
systemctl restart nfs
客戶端:
umount /mnt/public
umount /mnt/public
vim /etc/fstab
mount -a
問題4:dubbo rpc調用不通
需要在客戶端上面啓動openvpn
/etc/init.d/openvpn start
開啓NFS服務器
yum -y install nfs-utils (只安裝nfs-unitls) yum install nfs-utils rpcbind -y (安裝nfs-unitls和rpcbind服務,與上面二選一)
服務端:
$ vi /etc/exports
/public 192.168.245.1/24(ro)
/protected 192.168.245.1/24(rw)
systemctl reload nfs
客服端:
yum install -y nfs-utils
systemctl enable rpcbind.service
systemctl start rpcbind.service
[root@localhost ~]# vim /etc/fstab
192.168.245.128:/public /mnt/public nfs defaults 0 0
192.168.245.128:/protected /mnt/data nfs defaults 0 1
參考網站
微信公衆號: 互聯網技術的祕密 (intecsec)
官方網站: www.intecsec.com
個人微信號:sindoc
歡迎交流~