Deployment爲Pod和Replica Set下一代Replication Controller)提供聲明式更新html
apiVersion: apps/v1 # 1.9.0 以前的版本使用 apps/v1beta2,可經過命令 kubectl api-versions 查看 kind: Deployment #指定建立資源的角色/類型 metadata: #資源的元數據/屬性 name: nginx-deployment #資源的名字,在同一個namespace中必須惟一 namespace: xxxx #命名空間 labels: app: demo #標籤 spec: replicas: 3 #副本數量3 strategy: rollingUpdate: ##因爲replicas爲3,則整個升級,pod個數在2-4個之間 maxSurge: 1 #滾動升級時會先啓動1個pod maxUnavailable: 1 #滾動升級時容許的最大Unavailable的pod個數 selector: #定義標籤選擇器,部署須要管理的pod(帶有該標籤的的會被管理)需在pod 模板中定義 matchLabels: app: web-server template: #這裏Pod的定義 metadata: labels: #Pod的label app: web-server spec: # 模板的規範 containers: - name: nginx #容器的名字 image: nginx:1.12.1 #容器的鏡像地址 command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ] #啓動命令 args: #啓動參數 - '-storage.local.retention=$(STORAGE_RETENTION)' - '-storage.local.memory-chunks=$(STORAGE_MEMORY_CHUNKS)' - '-config.file=/etc/prometheus/prometheus.yml' - '-alertmanager.url=http://alertmanager:9093/alertmanager' - '-web.external-url=$(EXTERNAL_URL)' #若是command和args均沒有寫,那麼用Docker默認的配置。 #若是command寫了,但args沒有寫,那麼Docker默認的配置會被忽略並且僅僅執行.yaml文件的command(不帶任何參數的)。 #若是command沒寫,但args寫了,那麼Docker默認配置的ENTRYPOINT的命令行會被執行,可是調用的參數是.yaml中的args。 #若是若是command和args都寫了,那麼Docker默認的配置被忽略,使用.yaml的配置。 imagePullPolicy: IfNotPresent # IfNotPresent :默認值,本地有則使用本地鏡像,不拉取,若是不存在則拉取 # Always: 老是拉取 # Never: 只使用本地鏡像,從不拉取 livenessProbe: #表示container是否處於live狀態。若是LivenessProbe失敗,LivenessProbe將會通知kubelet對應的container不健康了。隨後kubelet將kill掉container,並根據RestarPolicy進行進一步的操做。默認狀況下LivenessProbe在第一次檢測以前初始化值爲Success,若是container沒有提供LivenessProbe,則也認爲是Success; httpGet: path: /health #若是沒有心跳檢測接口就爲/ port: 8080 scheme: HTTP initialDelaySeconds: 60 ##啓動後延時多久開始運行檢測 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 readinessProbe: readinessProbe: httpGet: path: /health #若是沒有心跳檢測接口就爲/ port: 8080 scheme: HTTP initialDelaySeconds: 30 ##啓動後延時多久開始運行檢測 timeoutSeconds: 5 successThreshold: 1 failureThreshold: 5 resources: ##CPU內存限制 requests: cpu: 2 memory: 2048Mi limits: cpu: 2 memory: 2048Mi env: ##經過環境變量的方式,直接傳遞pod=自定義Linux OS環境變量 - name: LOCAL_KEY #本地Key value: value - name: CONFIG_MAP_KEY #局策略可以使用configMap的配置Key, valueFrom: configMapKeyRef: name: special-config #configmap中找到name爲special-config key: special.type #找到name爲special-config裏data下的key ports: - name: http containerPort: 8080 #對service暴露端口 volumeMounts: #掛載volumes中定義的磁盤 - name: log-cache mount: /tmp/log - name: sdb #普通用法,該卷跟隨容器銷燬,掛載一個目錄 mountPath: /data/media - name: nfs-client-root #直接掛載硬盤方法,如掛載下面的nfs目錄到/mnt/nfs mountPath: /mnt/nfs - name: example-volume-config #高級用法第1種,將ConfigMap的log-script,backup-script分別掛載到/etc/config目錄下的一個相對路徑path/to/...下,若是存在同名文件,直接覆蓋。 mountPath: /etc/config - name: rbd-pvc #高級用法第2中,掛載PVC(PresistentVolumeClaim) #使用volume將ConfigMap做爲文件或目錄直接掛載,其中每個key-value鍵值對都會生成一個文件,key爲文件名,value爲內容, volumes: # 定義磁盤給上面volumeMounts掛載 - name: log-cache emptyDir: {} - name: sdb #掛載宿主機上面的目錄 hostPath: path: /any/path/it/will/be/replaced - name: example-volume-config # 供ConfigMap文件內容到指定路徑使用 configMap: name: example-volume-config #ConfigMap中名稱 items: - key: log-script #ConfigMap中的Key path: path/to/log-script #指定目錄下的一個相對路徑path/to/log-script - key: backup-script #ConfigMap中的Key path: path/to/backup-script #指定目錄下的一個相對路徑path/to/backup-script - name: nfs-client-root #供掛載NFS存儲類型 nfs: server: 10.42.0.55 #NFS服務器地址 path: /opt/public #showmount -e 看一下路徑 - name: rbd-pvc #掛載PVC磁盤 persistentVolumeClaim: claimName: rbd-pvc1 #掛載已經申請的pvc磁盤
一個典型的用例以下:
使用Deployment來建立ReplicaSet。ReplicaSet在後臺建立pod。檢查啓動狀態,看它是成功仍是失敗。
而後,經過更新Deployment的PodTemplateSpec字段來聲明Pod的新狀態。這會建立一個新的ReplicaSet,Deployment會按照控制的速率將pod從舊的ReplicaSet移動到新的ReplicaSet中。
若是當前狀態不穩定,回滾到以前的Deployment revision。每次回滾都會更新Deployment的revision。
擴容Deployment以知足更高的負載。
暫停Deployment來應用PodTemplateSpec的多個修復,而後恢復上線。
根據Deployment 的狀態判斷上線是否hang住了。
清除舊的沒必要要的ReplicaSetnode
建立deploymentmysql
kubectl create -f nginx-deployment.yaml --record ##--record 爲True 在annotation中記錄當前命令建立或者升級了該資源,如查看在每一個Deployment revision中執行了哪些命令 kubectl get deployments kubectl get rs #Replica Set的名字老是<Deployment的名字>-<pod template的hash值> kubectl get pods -n xxxx #命名空間 kubectl get pods --show-labels #查看標籤
更新deployment
注意: Deployment的rollout當且僅當Deployment的pod template(例如.spec.template)中的label更新或者鏡像更改時被觸發。其餘更新,例如擴容Deployment不會觸發rollout.nginx
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 #更新鏡像 或使用edit命令來編輯Deployment,修改 .spec.template.spec.containers[0].image ,將nginx:1.7.9 改寫成 nginx:1.9.1 kubectl edit deployment/nginx-deployment kubectl rollout status deployment/nginx-deployment #rollout狀態
回退deploymentweb
kubectl describe deployment #查看狀態 kubectl rollout history deployment/nginx-deployment #檢查升級記錄 kubectl rollout history deployment/nginx-deployment --revision=2 #查看version信息
暫停和恢復redis
kubectl get deploy
kubectl rollout pause deployment/nginx-deployment kubectl set image deploy/nginx nginx=nginx:1.9.1 kubectl rollout history deploy/nginx
service 的做用
防止Pod失去聯繫(服務發現)
定義一組Pod的訪問策略(負載均衡)
支持ClusterIP,NodePort以及LoadBalancer三種類型
Service的底層實現主要有iptables和ipvs兩種網絡模式算法
pod 與service的關係
經過lable-selector相關聯
經過Service實現Pod的負載均衡(TCP/UDP 4層)sql
[root@k8s-master-128 dome]# cat deploy-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: # 這裏是定義Deployment的標籤 app: nginx spec: replicas: 3 selector: matchLabels: app: nginx # 選擇關聯Deployment標籤 template: metadata: labels: # 給Pod定義一個標籤,方便其餘服務關聯這個Pod app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: # Service 的selector 指定標籤 app:nginx 來進行對Pod進行關聯 ;(這裏的app:nginx就是上面Deployment配置裏labels定義的標籤 ) app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: NodePort
發佈的服務類型有三種:ClusterIP、NodePort和LoadBalancer
官網地址:https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-typesdocker
分配一個內部集羣IP地址,只能在集羣內部訪問(同Namespaces內的Pod),不對外提供訪問服務!默認ServiceTpye
kubectl get svc 暴露的集羣ip和集羣端口,只能在k8s集羣內部訪問
Node節點上能查看到建立的iptables規則shell
分配一個內網集羣IP地址,並在內個節點上啓用一個端口來暴露服務,能夠在集羣外部訪問
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 # 須要暴露的集羣端口(service暴露的) targetPort: 9376 # 容器的端口(後端容器提供服務的端口) nodePort: 30000 type: NodePort
映射到物理機的端口範圍爲:The range of valid ports is 30000-32767
kubectl get svc -o wide 暴露的端口在node 節點上由kube-proxy來啓動並監聽的,可經過NodeIP+端口的方式直接進行訪問,由於kube-proxy進行了代理。
kube-proxy是如何代理訪問到容器的呢?由於kube-proxy在啓動的時候經過--proxy-mode=ipvs能夠指定底層內核代理模式,默認是iptables進行代理轉發,kube-proxy經過這兩種模式來代理直接對外提供服務
參考的寫法
apiVersion: v1 kind: Pod metadata: name: eureka labels: ccb: eureka spec: containers: - name: test-container image: eureka ports: - name: eureka containerPort: 8082 protocol: TCP imagePullPolicy: Never volumeMounts: - name: appconfig mountPath: /jar/application.yml subPath: application.yml volumes: - name: appconfig configMap: name: insight-application items: - key: registry-application.yml path: application.yml restartPolicy: Never --- apiVersion: v1 kind: Service metadata: name: eureka labels: ccb: eureka spec: ports: - port: 8082 targetPort: 8082 protocol: TCP nodePort: 30000 type: NodePort selector: ccb: eureka
分配一個內部集羣IP地址,並在每一個節點上啓用一個端口來暴露服務。
除此以外,Kubernetes會請求底層雲平臺上的負載均衡器,將每一個Node([NodeIP]:[NodePort])做爲後端添加進去。
LoadBalancer只適用於雲平臺,AWS默認就支持,阿里雲社區開發也支持
service有三組代理模式:userspace、iptables和ipvs
kubectl get svc -o wide kubectl describe pod nginx-deployment-6dd86d77d-kxkmt #注意命名空間
來源:https://nicksors.cc/2019/06/21/kubernetes%E7%B3%BB%E5%88%97%E4%B9%8B%E3%80%8AService%E3%80%8B.html
apiVersion: v1 kind: Pod metadata: name: eureka labels: ccb: eureka spec: containers: - name: test-container image: eureka ports: - name: eureka containerPort: 8082 protocol: TCP imagePullPolicy: Never #使用本地鏡像 volumeMounts: - name: appconfig mountPath: /jar/application.yml subPath: application.yml volumes: - name: appconfig configMap: name: insight-application items: - key: registry-application.yml path: application.yml restartPolicy: Never --- apiVersion: v1 kind: Service metadata: name: eureka labels: ccb: eureka spec: ports: - port: 8082 #集羣開放的的端口 targetPort: 8082 #後端容器開放的端口 protocol: TCP nodePort: 30000 #宿主機開放的端口,範圍大於30000 type: NodePort #指定service類型爲暴露物理節點的端口,必須 selector: ccb: eureka #service 管理的pod
用戶經過kubectl命令建立一個Pod的流程:
客戶端提交建立請求,能夠經過API Server的Restful API,也可使用kubectl工具,支持json和yaml格式;
Api Server處理用戶請求,存儲Pod信息數據到etcd集羣中;
Scheduler調度器經過API Server查看未綁定的Pod,嘗試爲Pod進行分配主機,經過調度算法選擇主機後,綁定到這臺機器上而且把調度信息寫入etcd集羣;
kubelet根據調度結果執行Pod建立操做,成功後將信息經過Api Server更新到etcd集羣中;
整個Pod建立過程完成,每一個組件都在於Api Server進行交互,Api Server就是k8s集羣的中間者,組件之間的協同者,是一個集羣訪問入口
2,Pod的多種控制器
ReplicaSet: 代用戶建立指定數量的pod副本數量,確保pod副本數量符合預期狀態,而且支持滾動式自動擴容和縮容功能。
ReplicaSet主要三個組件組成:
用戶指望的pod副本數量
標籤選擇器,判斷哪一個pod歸本身管理
當現存的pod數量不足,會根據pod資源模板進行新建幫助用戶管理無狀態的pod資源,精確反應用戶定義的目標數量,可是RelicaSet不是直接使用的控制器,而是使用Deployment。
Deployment:工做在ReplicaSet之上,用於管理無狀態應用,目前來講最好的控制器。支持滾動更新和回滾功能,還提供聲明式配置。 參考文章:https://blog.csdn.net/bbwangj/article/details/82011573
DaemonSet:用於確保集羣中的每個節點只運行特定的pod副本,一般用於實現系統級後臺任務,好比ingress,elk.服務是無狀態的,服務必須是守護進程。參考文章:https://www.cnblogs.com/xzkzzz/p/9553321.html
Job:只要任務或程序運行完成就當即退出,不須要重啓或重建。 參考文章:https://blog.csdn.net/bbwangj/article/details/82011610
Cronjob:週期性任務控制,執行後就退出, 不須要持續後臺運行, 參考文章:https://blog.csdn.net/bbwangj/article/details/82867830
StatefulSet:管理有狀態應用,好比redis,mysql
3,POD管理
# 建立Pod資源 $ kubectl create -f pod.yaml # 查看pods $ kubectl get pods nginx-pod # 查看pod描述 $ kubectl describe pod/nginx-pod # 更新資源 $ kubectl apply -f pod.yaml # 刪除資源 $kubectl delete -f pod.yaml or $kubectl delete pods nginx-pod
4,資源限制
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx resources: # 資源限制標籤 requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
requests和limits都是作資源限制的,他們的區別在於:
requests # pod在建立時向k8s請求的資源大小;
limits # 限制了這個Pod運行的最大資源空間;
5,調度約束
Pod.spec.nodeName # 強制約束Pod調度到指定Node節點上
Pod.spec.nodeSelector # 經過lable-selector機制選擇節點
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: # nodeName:node01 nodeSelector: env_role: dev containers: - name: nginx image: nignx
經過label給Node主機設置標籤:
kubectl label nodes k8s-node-129 env_role=dev
經過–show-labels查看Node的標籤:
$ kubectl get node --show-labels
6,重啓策略
Always: 當容器中止,老是重建容器,默認策略。
OnFailure: 當容器異常退出(退出狀態碼非0)時,才重啓容器。
Never:當容器終止退出,從不重啓容器。
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx restartPolicy: OnFailure
7,鏡像拉取策略
IfNotPresent:默認值,鏡像不存在宿主機上時才拉取
Always:每次建立Pod時都會從新拉取一次鏡像
Never:Pod永遠不會主動拉取這個鏡像
apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent
8,健康檢查
提供Probe機制,有如下兩種類型:
livenessProbe 若是檢查失敗,將容器殺死,根據Pod的restartPolicy來操做。 readinessProbe 若是檢查失敗,Kubeneres會把Pod從service endpoints中剔除。
robe支持如下三種檢查方法:
httpGet
發送HTTP請求,返回200-400範圍狀態碼爲成功。
exec
執行Shell命令返回狀態碼是0爲成功。
tcpSocket
發起TCP Socket創建成功。
9,問題定位
kubectl describe type/name kubectl logs type/name [-c container] kubectl exec --namespace=xxx -it pod -C 容器名稱 -- bash
來源:https://nicksors.cc/2019/06/18/kubernetes%E7%B3%BB%E5%88%97%E4%B9%8B%E3%80%8APod%E3%80%8B.html
1,命令生成
$ kubectl run --image=nginx my-deploy -o yaml --dry-run >my-deploy.yaml $ kubectl create -f deploy-nginx.yaml -o yaml --dry-run >my-deploy.yaml $ kubectl create -f deploy-nginx.yaml -o json --dry-run >my-deploy.json # 指定輸出json格式 – image # 指定模板鏡像 my-deploy # 運行標籤名稱 –dry-run # 只測試運行,不會實際運行pod -o yaml # 指定輸出格式
2,get導出
kubectl get deploy/my-deploy -o=yaml --export > my-deploy.yaml
3,查詢Pod容器的字段資源內部文檔
使用kubectl explain –help 查詢pod字段內部說明
$ kubectl explain pods # 每個層級的指令都會有字段信息 $ kubectl explain pods.spec $ kubectl explain pods.spec.containers