Kubernetes詳解

1.1 Kubernetes簡介

 

 

1.1.1 什麼是Kubernetes

Kubernetes (一般稱爲K8s,K8s是將8個字母「ubernete」替換爲「8」的縮寫) 是一個以容器爲中心的基礎架構,能夠實如今物理集羣或虛擬機集羣上調度和運行容器,提供容器自動部署、擴展和管理的開源平臺。知足了應用程序在生產環境中的一些通用需求:應用實例副本、水平自動擴展、命名與發現、負載均衡、滾動升級、資源監控等。html

1.1.2 Kubernetes發展史

Kubernetes (希臘語"舵手" 或 "飛行員") 由Joe Beda,Brendan Burns和Craig McLuckie創立,並由其餘谷歌工程師,包括Brian Grant和Tim Hockin進行加盟創做,並由谷歌在2014年首次對外宣佈 。它的開發和設計都深受谷歌的Borg系統的影響,它的許多頂級貢獻者以前也是Borg系統的開發者。在谷歌內部,Kubernetes的原始代號曾經是Seven,即星際迷航中友好的Borg(博格人)角色。Kubernetes標識中舵輪有七個輪輻就是對該項目代號的致意。node

Kubernetes v1.0於2015年7月21日發佈。隨着v1.0版本發佈,谷歌與Linux 基金會合做組建了Cloud Native Computing Foundation (CNCF)並把Kubernetes做爲種子技術來提供。mysql

Rancher Labs在其Rancher容器管理平臺中包含了Kubernetes的發佈版。Kubernetes也在不少其餘公司的產品中被使用,好比Red Hat在OpenShift產品中,CoreOS的Tectonic產品中, 以及IBM的IBM雲私有產品中。linux

1.1.3 Kubernetes 特色

一、可移植: 支持公有云,私有云,混合雲,多重雲(multi-cloud)nginx

二、可擴展: 模塊化, 插件化, 可掛載, 可組合git

三、自動化: 自動部署,自動重啓,自動複製,自動伸縮/擴展github

四、快速部署應用,快速擴展應用golang

五、無縫對接新的應用功能web

六、節省資源,優化硬件資源的使用sql

1.1.4 Kubernetes核心組件

Kubernetes遵循master-slave architecture。Kubernetes的組件能夠分爲管理單個的 node 組件和控制平面的一部分的組件。

Kubernetes Master是集羣的主要控制單元,用於管理其工做負載並指導整個系統的通訊。Kubernetes控制平面由各自的進程組成,每一個組件均可以在單個主節點上運行,也能夠在支持high-availability clusters的多個主節點上運行。

Kubernetes主要由如下幾個核心組件組成:

組件名稱

說明

etcd

保存了整個集羣的狀態;

apiserver

提供了資源操做的惟一入口,並提供認證、受權、訪問控制、API註冊和發現等機制;

controller manager

負責維護集羣的狀態,好比故障檢測、自動擴展、滾動更新等;

scheduler

負責資源的調度,按照預約的調度策略將Pod調度到相應的機器上;

kubelet

負責維護容器的生命週期,同時也負責Volume(CVI)和網絡(CNI)的管理;

Container runtime

負責鏡像管理以及Pod和容器的真正運行(CRI);

kube-proxy

負責爲Service提供cluster內部的服務發現和負載均衡;

核心組件結構圖

 

 

除了核心組件,還有一些推薦的Add-ons:

組件名稱

說明

kube-dns

負責爲整個集羣提供DNS服務

Ingress Controller

爲服務提供外網入口

Heapster

提供資源監控

Dashboard

提供GUI

Federation

提供跨可用區的集羣

Fluentd-elasticsearch

提供集羣日誌採集、存儲與查詢

1.2 部署Kubernetes集羣

1.2.1 主機環境說明

系統版本說明

[root@k8s-master ~]# cat /etc/redhat-release

CentOS Linux release 7.2.1511 (Core)

[root@k8s-master ~]# uname -r

3.10.0-327.el7.x86_64

[root@k8s-master ~]# getenforce

Disabled

[root@k8s-master ~]# systemctl status  firewalld.service

● firewalld.service - firewalld - dynamic firewall daemon

   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)

   Active: inactive (dead)

主機IP規劃

主機名    IP     功能

k8s-master      10.0.0.11/172.16.1.11   Master

k8s-node-1      10.0.0.12/172.16.1.12   node1

k8s-node-2      10.0.0.13/172.16.1.13   node2

設置hosts解析

[root@k8s-master ~]# cat /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

10.0.0.11   k8s-master

10.0.0.12   k8s-node-1

10.0.0.13   k8s-node-2

1.2.2 安裝軟件包

在三個節點上分別操做

[root@k8s-master ~]# yum install etcd docker kubernetes flannel  -y

[root@k8s-node-1 ~]# yum install docker kubernetes flannel  -y

[root@k8s-node-2 ~]# yum install docker kubernetes flannel  -y

安裝的軟件版本說明

[root@k8s-master ~]# rpm -qa  etcd docker kubernetes flannel

flannel-0.7.1-2.el7.x86_64

docker-1.12.6-71.git3e8e77d.el7.centos.1.x86_64

kubernetes-1.5.2-0.7.git269f928.el7.x86_64

etcd-3.2.11-1.el7.x86_64

1.2.3 修改配置etcd

         yum安裝的etcd默認配置文件在/etc/etcd/etcd.conf。

最終配置文件

[root@k8s-master ~]# grep -Ev '^$|#' /etc/etcd/etcd.conf

ETCD_DATA_DIR="/var/lib/etcd/default.etcd"

ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"

ETCD_NAME="default"

ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.11:2379"

啓動etcd

[root@k8s-master ~]# systemctl enable etcd

[root@k8s-master ~]# systemctl start etcd

測試etcd

etcdctl set testdir/testkey0 0

etcdctl set testdir/testkey0 0

[root@k8s-master ~]# etcdctl -C http://10.0.0.11:2379 cluster-health

member 8e9e05c52164694d is healthy: got healthy result from http://10.0.0.11:2379

cluster is healthy

1.2.4 配置並啓動kubernetes

/etc/kubernetes/apiserver配置文件內容

[root@k8s-master ~]#  grep -Ev '^$|#'  /etc/kubernetes/apiserver

KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"

KUBE_API_PORT="--port=8080"

KUBE_ETCD_SERVERS="--etcd-servers=http://10.0.0.11:2379"

KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

KUBE_API_ARGS=""

/etc/kubernetes/config配置文件

[root@k8s-master ~]#  grep -Ev '^$|#' /etc/kubernetes/config

KUBE_LOGTOSTDERR="--logtostderr=true"

KUBE_LOG_LEVEL="--v=0"

KUBE_ALLOW_PRIV="--allow-privileged=false"

KUBE_MASTER="--master=http://10.0.0.11:8080"

啓動服務

systemctl enable kube-apiserver.service

systemctl start kube-apiserver.service

systemctl enable kube-controller-manager.service

systemctl start kube-controller-manager.service

systemctl enable kube-scheduler.service

systemctl start kube-scheduler.service

1.2.5 部署配置node

/etc/kubernetes/config配置文件

[root@k8s-node-1 ~]# grep -Ev '^$|#'  /etc/kubernetes/config

KUBE_LOGTOSTDERR="--logtostderr=true"

KUBE_LOG_LEVEL="--v=0"

KUBE_ALLOW_PRIV="--allow-privileged=false"

KUBE_MASTER="--master=http://10.0.0.11:8080"

[root@k8s-node-1 ~]# grep -Ev '^$|#'  /etc/kubernetes/kubelet

KUBELET_ADDRESS="--address=0.0.0.0"

KUBELET_HOSTNAME="--hostname-override=10.0.0.12"

KUBELET_API_SERVER="--api-servers=http://10.0.0.11:8080"

KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"

KUBELET_ARGS=""

/etc/kubernetes/config配置文件

[root@k8s-node-2 ~]# grep -Ev '^$|#'  /etc/kubernetes/config

KUBE_LOGTOSTDERR="--logtostderr=true"

KUBE_LOG_LEVEL="--v=0"

KUBE_ALLOW_PRIV="--allow-privileged=false"

KUBE_MASTER="--master=http://10.0.0.11:8080"

[root@k8s-node-2 ~]# grep -Ev '^$|#'  /etc/kubernetes/kubelet

KUBELET_ADDRESS="--address=0.0.0.0"

KUBELET_HOSTNAME="--hostname-override=10.0.0.13"

KUBELET_API_SERVER="--api-servers=http://10.0.0.11:8080"

KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"

KUBELET_ARGS=""

啓動

systemctl enable kubelet.service

systemctl start kubelet.service

systemctl enable kube-proxy.service

systemctl start kube-proxy.service

在master上查看集羣中節點及節點狀態

# kubectl -s http://10.0.0.11:8080 get node

[root@k8s-master ~]# kubectl -s http://10.0.0.11:8080 get node

NAME        STATUS    AGE

10.0.0.12   Ready     49s

10.0.0.13   Ready     56s

[root@k8s-master ~]# kubectl get nodes

NAME        STATUS    AGE

10.0.0.12   Ready     1m

10.0.0.13   Ready     1m

         至此Kubernetes基礎部署完成

1.2.6 Kubernetes其餘安裝方法介紹和總結

二進制安裝:

能夠安裝最新版的1.9,二進制安裝須要手動建立配置文件和systemd啓動文件,優點是有助於理解系統各組件的交互原理和熟悉組件啓動參數,有助於快速排查解決實際問題

kubuadm:

kubeadm是Kubernetes官方推出的快速部署Kubernetes集羣工具,其思路是將Kubernetes相關服務容器化(Kubernetes靜態Pod)以簡化部署。

minikube:

minikube 由 CoreOS 提供在單機上構件 kubernetes 集羣。minikube命令能夠運行在windows/linux/macos等平臺,使用minikube搭建本地集羣是很是方便的,同時minikube提供了完整的kubernetes集羣的功能。對於初識者minikube是一種很好的安裝方式,並且上手也很是快。但問題在於minikube安裝的時候須要鏈接互聯網,並且網絡須要足夠好

編譯安裝:

kubernetes是使用golang開發的,編譯安裝須要go環境,編譯時間特別長,不建議

ansible部署:

因爲k8s部署二進制安裝步驟較多,因而有網友將其寫成ansible劇本簡化部署https://github.com/gjmzj/kubeasz

1.3 建立覆蓋網絡--Flannel

1.3.1 配置Flannel(全部節點操做)

安裝軟件包

yum install flannel

修改配置文件

[root@k8s-master ~]# grep "^[a-Z]" /etc/sysconfig/flanneld

FLANNEL_ETCD_ENDPOINTS="http://10.0.0.11:2379"

FLANNEL_ETCD_PREFIX="/atomic.io/network"

1.3.2 配置etcd中關於flannel的key

Flannel使用Etcd進行配置,來保證多個Flannel實例之間的配置一致性,因此須要在etcd上進行以下配置:(‘/atomic.io/network/config’這個key與上文/etc/sysconfig/flannel中的配置項FLANNEL_ETCD_PREFIX是相對應的,錯誤的話啓動就會出錯)

配置網絡範圍

etcdctl mk  /atomic.io/network/config '{ "Network": "172.16.0.0/16" }'

操做建立網絡

[root@k8s-master ~]# etcdctl mk /atomic.io/network/config '{ "Network": "172.16.0.0/16" }'

{ "Network": "172.16.0.0/16" }

master節點操做

         systemctl enable flanneld.service

         systemctl start flanneld.service

         service docker restart

         systemctl restart kube-apiserver.service

         systemctl restart kube-controller-manager.service

         systemctl restart kube-scheduler.service

node節點操做

         systemctl enable flanneld.service

         systemctl start flanneld.service

         service docker restart

         systemctl restart kubelet.service

         systemctl restart kube-proxy.service

 

1.4  k8s核心概念

1.4.一、Pod

  Pod 是Kubernetes的基本操做單元,也是應用運行的載體。整個Kubernetes系統都是圍繞着Pod展開的,好比如何部署運行Pod、如何保證Pod的數量、如何訪問Pod等。另外,Pod是一個或多個機關容器的集合,這能夠說是一大創新點,提供了一種容器的組合的模型。

1.4.1.1 基本操做

建立

kubectl create -f xxx.yaml

查詢

kubectl get pod yourPodName

kubectl describe pod yourPodName

刪除

kubectl delete pod yourPodName

更新

kubectl replace /path/to/yourNewYaml.yaml

1.4.1.2  Pod與容器

  在Docker中,容器是最小的處理單元,增刪改查的對象是容器,容器是一種虛擬化技術,容器之間是隔離的,隔離是基於Linux Namespace實現的。而在Kubernetes中,Pod包含一個或者多個相關的容器,Pod能夠認爲是容器的一種延伸擴展,一個Pod也是一個隔離體,而Pod內部包含的一組容器又是共享的(包括PID、Network、IPC、UTS)。除此以外,Pod中的容器能夠訪問共同的數據捲來實現文件系統的共享。

1.4.1.3 鏡像

  在kubernetes中,鏡像的下載策略爲:

    Always:每次都下載最新的鏡像

    Never:只使用本地鏡像,從不下載

    IfNotPresent:只有當本地沒有的時候才下載鏡像

  Pod被分配到Node以後會根據鏡像下載策略進行鏡像下載,能夠根據自身集羣的特色來決定採用何種下載策略。不管何種策略,都要確保Node上有正確的鏡像可用。

1.4.1.4 其餘設置

  經過yaml文件,能夠在Pod中設置:

    啓動命令,如:spec-->containers-->command;

    環境變量,如:spec-->containers-->env-->name/value;

    端口橋接,如:spec-->containers-->ports-->containerPort/protocol/hostIP/hostPort(使用hostPort時須要注意端口衝突的問題,不過Kubernetes在調度Pod的時候會檢查宿主機端口是否衝突,好比當兩個Pod均要求綁定宿主機的80端口,Kubernetes將會將這兩個Pod分別調度到不一樣的機器上);

    Host網絡,一些特殊場景下,容器必需要以host方式進行網絡設置(如接收物理機網絡纔可以接收到的組播流),在Pod中也支持host網絡的設置,如:spec-->hostNetwork=true;

    數據持久化,如:spec-->containers-->volumeMounts-->mountPath;

    重啓策略,當Pod中的容器終止退出後,重啓容器的策略。這裏的所謂Pod的重啓,實際上的作法是容器的重建,以前容器中的數據將會丟失,若是須要持久化數據,那麼須要使用數據捲進行持久化設置。Pod支持三種重啓策略:Always(默認策略,當容器終止退出後,老是重啓容器)、OnFailure(當容器終止且異常退出時,重啓)、Never(從不重啓);

 

1.4.二、Replication Controller

  Replication Controller(RC)是Kubernetes中的另外一個核心概念,應用託管在Kubernetes以後,Kubernetes須要保證應用可以持續運行,這是RC的工做內容,它會確保任什麼時候間Kubernetes中都有指定數量的Pod在運行。在此基礎上,RC還提供了一些更高級的特性,好比滾動升級、升級回滾等。

1.4.2.1 RC與Pod的關聯——Label

  RC與Pod的關聯是經過Label來實現的。Label機制是Kubernetes中的一個重要設計,經過Label進行對象的弱關聯,能夠靈活地進行分類和選擇。對於Pod,須要設置其自身的Label來進行標識,Label是一系列的Key/value對,在Pod-->metadata-->labeks中進行設置。

  Label的定義是任一的,可是Label必須具備可標識性,好比設置Pod的應用名稱和版本號等。另外Lable是不具備惟一性的,爲了更準確的標識一個Pod,應該爲Pod設置多個維度的label。以下:

    "release" : "stable", "release" : "canary"

    "environment" : "dev", "environment" : "qa", "environment" : "production"

    "tier" : "frontend", "tier" : "backend", "tier" : "cache"

    "partition" : "customerA", "partition" : "customerB"

    "track" : "daily", "track" : "weekly"

  舉例,當你在RC的yaml文件中定義了該RC的selector中的label爲app:my-web,那麼這個RC就會去關注Pod-->metadata-->labeks中label爲app:my-web的Pod。修改了對應Pod的Label,就會使Pod脫離RC的控制。一樣,在RC運行正常的時候,若試圖繼續建立一樣Label的Pod,是建立不出來的。由於RC認爲副本數已經正常了,再多起的話會被RC刪掉的。

1.4.2.2 彈性伸縮

  彈性伸縮是指適應負載變化,以彈性可伸縮的方式提供資源。反映到Kubernetes中,指的是可根據負載的高低動態調整Pod的副本數量。調整Pod的副本數是經過修改RC中Pod的副本是來實現的,示例命令以下:

  擴容Pod的副本數目到10

$ kubectl scale relicationcontroller yourRcName --replicas=10

  縮容Pod的副本數目到1

$ kubectl scale relicationcontroller yourRcName --replicas=1

 

1.4.2.3 滾動升級

  滾動升級是一種平滑過渡的升級方式,經過逐步替換的策略,保證總體系統的穩定,在初始升級的時候就能夠及時發現、調整問題,以保證問題影響度不會擴大。Kubernetes中滾動升級的命令以下:

$ kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s

  升級開始後,首先依據提供的定義文件建立V2版本的RC,而後每隔10s(--update-period=10s)逐步的增長V2版本的Pod副本數,逐步減小V1版本Pod的副本數。升級完成以後,刪除V1版本的RC,保留V2版本的RC,及實現滾動升級。

  升級過程當中,發生了錯誤中途退出時,能夠選擇繼續升級。Kubernetes可以智能的判斷升級中斷以前的狀態,而後緊接着繼續執行升級。固然,也能夠進行回退,命令以下:

$ kubectl rolling-update my-rcName-v1 -f my-rcName-v2-rc.yaml --update-period=10s --rollback

回退的方式實際就是升級的逆操做,逐步增長V1.0版本Pod的副本數,逐步減小V2版本Pod的副本數。

1.4.2.4 新一代副本控制器replica set

  這裏所說的replica set,能夠被認爲 是「升級版」的Replication Controller。也就是說。replica set也是用於保證與label selector匹配的pod數量維持在指望狀態。區別在於,replica set引入了對基於子集的selector查詢條件,而Replication Controller僅支持基於值相等的selecto條件查詢。這是目前從用戶角度餚,二者惟一的顯著差別。 社區引入這一API的初衷是用於取代vl中的Replication Controller,也就是說.當v1版本被廢棄時,Replication Controller就完成了它的歷史使命,而由replica set來接管其工做。雖然replica set能夠被單獨使用,可是目前它多被Deployment用於進行pod的建立、更新與刪除。Deployment在滾動更新等方面提供了不少很是有用的功能,關於DeplOymCn的更多信息,讀者們能夠在後續小節中得到。 

1.4.三、Service

  爲了適應快速的業務需求,微服務架構已經逐漸成爲主流,微服務架構的應用須要有很是好的服務編排支持。Kubernetes中的核心要素Service便提供了一套簡化的服務代理和發現機制,自然適應微服務架構。

1.4.3.1 原理

  在Kubernetes中,在受到RC調控的時候,Pod副本是變化的,對於的虛擬IP也是變化的,好比發生遷移或者伸縮的時候。這對於Pod的訪問者來講是不可接受的。Kubernetes中的Service是一種抽象概念,它定義了一個Pod邏輯集合以及訪問它們的策略,Service同Pod的關聯一樣是居於Label來完成的。Service的目標是提供一種橋樑, 它會爲訪問者提供一個固定訪問地址,用於在訪問時重定向到相應的後端,這使得非 Kubernetes原生應用程序,在無須爲Kubemces編寫特定代碼的前提下,輕鬆訪問後端。

  Service同RC同樣,都是經過Label來關聯Pod的。當你在Service的yaml文件中定義了該Service的selector中的label爲app:my-web,那麼這個Service會將Pod-->metadata-->labeks中label爲app:my-web的Pod做爲分發請求的後端。當Pod發生變化時(增長、減小、重建等),Service會及時更新。這樣一來,Service就能夠做爲Pod的訪問入口,起到代理服務器的做用,而對於訪問者來講,經過Service進行訪問,無需直接感知Pod。

  須要注意的是,Kubernetes分配給Service的固定IP是一個虛擬IP,並非一個真實的IP,在外部是沒法尋址的。真實的系統實現上,Kubernetes是經過Kube-proxy組件來實現的虛擬IP路由及轉發。因此在以前集羣部署的環節上,咱們在每一個Node上均部署了Proxy這個組件,從而實現了Kubernetes層級的虛擬轉發網絡。

 

1.4.3.2 Service內部負載均衡

  當Service的Endpoints包含多個IP的時候,及服務代理存在多個後端,將進行請求的負載均衡。默認的負載均衡策略是輪訓或者隨機(有kube-proxy的模式決定)。同時,Service上經過設置Service-->spec-->sessionAffinity=ClientIP,來實現基於源IP地址的會話保持。

1.4.3.3 發佈Service

  Service的虛擬IP是由Kubernetes虛擬出來的內部網絡,外部是沒法尋址到的。可是有些服務又須要被外部訪問到,例如web前段。這時候就須要加一層網絡轉發,即外網到內網的轉發。Kubernetes提供了NodePort、LoadBalancer、Ingress三種方式。

    NodePort,在以前的Guestbook示例中,已經延時了NodePort的用法。NodePort的原理是,Kubernetes會在每個Node上暴露出一個端口:nodePort,外部網絡能夠經過(任一Node)[NodeIP]:[NodePort]訪問到後端的Service。

    LoadBalancer,在NodePort基礎上,Kubernetes能夠請求底層雲平臺建立一個負載均衡器,將每一個Node做爲後端,進行服務分發。該模式須要底層雲平臺(例如GCE)支持。

    Ingress,是一種HTTP方式的路由轉發機制,由Ingress Controller和HTTP代理服務器組合而成。Ingress Controller實時監控Kubernetes API,實時更新HTTP代理服務器的轉發規則。HTTP代理服務器有GCE Load-Balancer、HaProxy、Nginx等開源方案。

1.4.3.3 servicede 自發性機制

  Kubernetes中有一個很重要的服務自發現特性。一旦一個service被建立,該service的service IP和service port等信息均可以被注入到pod中供它們使用。Kubernetes主要支持兩種service發現 機制:環境變量和DNS。

環境變量方式

  Kubernetes建立Pod時會自動添加全部可用的service環境變量到該Pod中,若有須要.這些環境變量就被注入Pod內的容器裏。須要注意的是,環境變量的注入只發送在Pod建立時,且不會被自動更新。這個特色暗含了service和訪問該service的Pod的建立時間的前後順序,即任何想要訪問service的pod都須要在service已經存在後建立,不然與service相關的環境變量就沒法注入該Pod的容器中,這樣先建立的容器就沒法發現後建立的service。

DNS方式

  Kubernetes集羣如今支持增長一個可選的組件——DNS服務器。這個DNS服務器使用Kubernetes的watchAPI,不間斷的監測新的service的建立併爲每一個service新建一個DNS記錄。若是DNS在整個集羣範圍內均可用,那麼全部的Pod都可以自動解析service的域名。Kube-DNS搭建及更詳細的介紹請見:基於Kubernetes集羣部署skyDNS服務

1.4.3.4 多個service如何避免地址和端口衝突

  此處設計思想是,Kubernetes經過爲每一個service分配一個惟一的ClusterIP,因此當使用ClusterIP:port的組合訪問一個service的時候,無論port是什麼,這個組合是必定不會發生重複的。另外一方面,kube-proxy爲每一個service真正打開的是一個絕對不會重複的隨機端口,用戶在service描述文件中指定的訪問端口會被映射到這個隨機端口上。這就是爲何用戶能夠在建立service時隨意指定訪問端口。

 

1.4.四、Deployment

  Kubernetes提供了一種更加簡單的更新RC和Pod的機制,叫作Deployment。經過在Deployment中描述你所指望的集羣狀態,Deployment Controller會將如今的集羣狀態在一個可控的速度下逐步更新成你所指望的集羣狀態。Deployment主要職責一樣是爲了保證pod的數量和健康,90%的功能與Replication Controller徹底同樣,能夠看作新一代的Replication Controller。可是,它又具有了Replication Controller以外的新特性:

    Replication Controller所有功能:Deployment繼承了上面描述的Replication Controller所有功能。

    事件和狀態查看:能夠查看Deployment的升級詳細進度和狀態。

    回滾:當升級pod鏡像或者相關參數的時候發現問題,可使用回滾操做回滾到上一個穩定的版本或者指定的版本。

    版本記錄: 每一次對Deployment的操做,都能保存下來,給予後續可能的回滾使用。

    暫停和啓動:對於每一次升級,都可以隨時暫停和啓動。

    多種升級方案:Recreate----刪除全部已存在的pod,從新建立新的; RollingUpdate----滾動升級,逐步替換的策略,同時滾動升級時,支持更多的附加參數,例如設置最大不可用pod數量,最小升級間隔時間等等。

1.4.4.1 滾動升級

  相比於RC,Deployment直接使用kubectl edit deployment/deploymentName 或者kubectl set方法就能夠直接升級(原理是Pod的template發生變化,例如更新label、更新鏡像版本等操做會觸發Deployment的滾動升級)。操做示例——首先 咱們一樣定義一個nginx-deploy-v1.yaml的文件,副本數量爲2:

 

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: nginx-deployment

spec:

  replicas: 3

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: nginx:1.7.9

        ports:

        - containerPort: 80

 

  建立deployment:

 

$ kubectl create -f nginx-deploy-v1.yaml --record

deployment "nginx-deployment" created

$ kubectl get deployments

NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

nginx-deployment   3         0         0            0           1s

$ kubectl get deployments

NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

nginx-deployment   3         3         3            3           18s

 

  正常以後,將nginx的版本進行升級,從1.7升級到1.9。第一種方法,直接set鏡像:

$ kubectl set image deployment/nginx-deployment2 nginx=nginx:1.9

deployment "nginx-deployment2" image updated

  第二種方法,直接edit:

$ kubectl edit deployment/nginx-deployment

deployment "nginx-deployment2" edited

  查看Deployment的變動信息(如下信息得以保存,是建立時候加的「--record」這個選項起的做用):

 

$ kubectl rollout history deployment/nginx-deployment

deployments "nginx-deployment":

REVISION    CHANGE-CAUSE

1           kubectl create -f docs/user-guide/nginx-deployment.yaml --record

2           kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

3           kubectl set image deployment/nginx-deployment nginx=nginx:1.91

 

$ kubectl rollout history deployment/nginx-deployment --revision=2

deployments "nginx-deployment" revision 2

  Labels:       app=nginx

          pod-template-hash=1159050644

  Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1

  Containers:

   nginx:

    Image:      nginx:1.9.1

    Port:       80/TCP

     QoS Tier:

        cpu:      BestEffort

        memory:   BestEffort

    Environment Variables:      <none>

  No volumes.

 

  最後介紹下Deployment的一些基礎命令。

$ kubectl describe deployments  #查詢詳細信息,獲取升級進度

$ kubectl rollout pause deployment/nginx-deployment2  #暫停升級

$ kubectl rollout resume deployment/nginx-deployment2  #繼續升級

$ kubectl rollout undo deployment/nginx-deployment2  #升級回滾

$ kubectl scale deployment nginx-deployment --replicas 10  #彈性伸縮Pod數量

  關於多重升級,舉例,當你建立了一個nginx1.7的Deployment,要求副本數量爲5以後,Deployment Controller會逐步的將5個1.7的Pod啓動起來;當啓動到3個的時候,你又發出更新Deployment中Nginx到1.9的命令;這時Deployment Controller會當即將已啓動的3個1.7Pod殺掉,而後逐步啓動1.9的Pod。Deployment Controller不會等到1.7的Pod都啓動完成以後,再依次殺掉1.7,啓動1.9。

 

1.4.五、Volume

  在Docker的設計實現中,容器中的數據是臨時的,即當容器被銷燬時,其中的數據將會丟失。若是須要持久化數據,須要使用Docker數據卷掛載宿主機上的文件或者目錄到容器中。在Kubernetes中,當Pod重建的時候,數據是會丟失的,Kubernetes也是經過數據卷掛載來提供Pod數據的持久化的。Kubernetes數據卷是對Docker數據卷的擴展,Kubernetes數據卷是Pod級別的,能夠用來實現Pod中容器的文件共享。目前,Kubernetes支持的數據卷類型以下:

    1)        EmptyDir

    2)        HostPath

    3)        GCE Persistent Disk

    4)        AWS Elastic Block Store

    5)        NFS

    6)        iSCSI

    7)        Flocker

    8)        GlusterFS

    9)        RBD

    10)    Git Repo

    11)    Secret

    12)    Persistent Volume Claim

1.4.5.1 Persistent Volume和Persistent Volume Claim

  理解每一個存儲系統是一件複雜的事情,特別是對於普通用戶來講,有時候並不須要關心各類存儲實現,只但願可以安全可靠地存儲數據。Kubernetes中提供了Persistent Volume和Persistent Volume Claim機制,這是存儲消費模式。Persistent Volume是由系統管理員配置建立的一個數據卷(目前支持HostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、iSCSI、GlusterFS、RBD),它表明了某一類存儲插件實現;而對於普通用戶來講,經過Persistent Volume Claim可請求並得到合適的Persistent Volume,而無須感知後端的存儲實現。Persistent Volume和Persistent Volume Claim的關係其實相似於Pod和Node,Pod消費Node資源,Persistent Volume Claim則消費Persistent Volume資源。Persistent Volume和Persistent Volume Claim相互關聯,有着完整的生命週期管理:

    1)        準備:系統管理員規劃或建立一批Persistent Volume;

    2)        綁定:用戶經過建立Persistent Volume Claim來聲明存儲請求,Kubernetes發現有存儲請求的時候,就去查找符合條件的Persistent Volume(最小知足策略)。找到合適的就綁定上,找不到就一直處於等待狀態;

    3)        使用:建立Pod的時候使用Persistent Volume Claim;

    4)        釋放:當用戶刪除綁定在Persistent Volume上的Persistent Volume Claim時,Persistent Volume進入釋放狀態,此時Persistent Volume中還殘留着上一個Persistent Volume Claim的數據,狀態還不可用;

    5)        回收:是否的Persistent Volume須要回收才能再次使用。回收策略能夠是人工的也能夠是Kubernetes自動進行清理(僅支持NFS和HostPath)

1.4.六、Horizontal Pod Autoscaler

  自動擴展做爲一個長久的議題,一直爲人們津津樂道。系統可以根據負載的變化對計算資源的分配進行自動的擴增或者收縮,無疑是一個很是吸引人的特徵,它可以最大可能地減小費用或者其餘代價(如電力損耗)。自動擴展主要分爲兩種,其一爲水平擴展,針對於實例數目的增減;其二爲垂直擴展,即單個實例可使用的資源的增減。Horizontal Pod Autoscaler(HPA)屬於前者。

1.4.6.1 Horizontal Pod Autoscaler如何工做

  Horizontal Pod Autoscaler的操做對象是Replication Controller、ReplicaSet或Deployment對應的Pod,根據觀察到的CPU實際使用量與用戶的指望值進行比對,作出是否須要增減實例數量的決策。controller目前使用heapSter來檢測CPU使用量,檢測週期默認是30秒。

1.4.6.2 Horizontal Pod Autoscaler的決策策略

  在HPA Controller檢測到CPU的實際使用量以後,會求出當前的CPU使用率(實際使用量與pod 請求量的比率)。而後,HPA Controller會經過調整副本數量使得CPU使用率儘可能向指望值靠近.另外,考慮到自動擴展的決策可能須要一段時間纔會生效,甚至在短期內會引入一些噪聲. 例如當pod所須要的CPU負荷過大,從而運行一個新的pod進行分流,在建立的過程當中,系統的CPU使用量可能會有一個攀升的過程。因此,在每一次做出決策後的一段時間內,將再也不進行擴展決策。對於ScaleUp而言,這個時間段爲3分鐘,Scaledown爲5分鐘。再者HPA Controller容許必定範圍內的CPU使用量的不穩定,也就是說,只有當aVg(CurrentPodConsumption/Target低於0.9或者高於1.1時才進行實例調整,這也是出於維護系統穩定性的考慮。

 

1.5 基於kubernetes集羣部署DashBoard

1.5.1  準備yaml配置文件

編輯dashboard.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

# Keep the name in sync with image version and

# gce/coreos/kube-manifests/addons/dashboard counterparts

  name: kubernetes-dashboard-latest

  namespace: kube-system

spec:

  replicas: 1

  template:

    metadata:

      labels:

        k8s-app: kubernetes-dashboard

        version: latest

        kubernetes.io/cluster-service: "true"

    spec:

      containers:

      - name: kubernetes-dashboard

        image: index.tenxcloud.com/google_containers/kubernetes-dashboard-amd64:v1.4.1

        resources:

          # keep request = limit to keep this container in guaranteed class

          limits:

            cpu: 100m

            memory: 50Mi

          requests:

            cpu: 100m

            memory: 50Mi

        ports:

        - containerPort: 9090

        args:

         -  --apiserver-host=http://10.0.0.11:8080

        livenessProbe:

          httpGet:

            path: /

            port: 9090

          initialDelaySeconds: 30

          timeoutSeconds: 30

 

編輯dashboardsvc.yaml文件

apiVersion: v1

kind: Service

metadata:

  name: kubernetes-dashboard

  namespace: kube-system

  labels:

    k8s-app: kubernetes-dashboard

    kubernetes.io/cluster-service: "true"

spec:

  selector:

    k8s-app: kubernetes-dashboard

  ports:

  - port: 80

    targetPort: 9090

 

1.5.2  啓動

在master執行以下命令:

kubectl create -f dashboard.yaml

kubectl create -f dashboardsvc.yaml

 

1.5.3  驗證

[root@k8s-master ~]# kubectl get deployment --all-namespaces

NAMESPACE NAME DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

kube-system kubernetes-dashboard-latest 1  1         1            1           1h

[root@k8s-master ~]# kubectl get svc  --all-namespaces

NAMESPACE   NAME          CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE

default       kubernetes             10.254.0.1      <none>        443/TCP   9d

kube-system   kubernetes-dashboard   10.254.44.119   <none>        80/TCP    1h

[root@k8s-master ~]# kubectl get pod  -o wide  --all-namespaces

NAMESPACE  NAME  READY     STATUS    RESTARTS     AGE   IP  NODE

kube-system kubernetes-dashboard-latest-3866786896-vsf3h 1/1 Running 0 1h 10.0.82.2 k8s-node-1

 

打開瀏覽器訪問:http://10.0.0.11:8080/ui/

 

 

 

1.6  kubernetes集羣配置dns

1.6.1 準備 yaml配置文件

編輯skydns-rc.yaml文件

# Copyright 2016 The Kubernetes Authors.

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

#     http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

 

# TODO - At some point, we need to rename all skydns-*.yaml.* files to kubedns-*.yaml.*

# Should keep target in cluster/addons/dns-horizontal-autoscaler/dns-horizontal-autoscaler.yaml

# in sync with this file.

 

# __MACHINE_GENERATED_WARNING__

 

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

  name: kube-dns

  namespace: kube-system

  labels:

    k8s-app: kube-dns

    kubernetes.io/cluster-service: "true"

spec:

  replicas: 1

  # replicas: not specified here:

  # 1. In order to make Addon Manager do not reconcile this replicas parameter.

  # 2. Default is 1.

  # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.

  strategy:

    rollingUpdate:

      maxSurge: 10%

      maxUnavailable: 0

  selector:

    matchLabels:

      k8s-app: kube-dns

  template:

    metadata:

      labels:

        k8s-app: kube-dns

      annotations:

        scheduler.alpha.kubernetes.io/critical-pod: ''

        scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'

    spec:

      containers:

      - name: kubedns

        image: myhub.fdccloud.com/library/kubedns-amd64:1.9

        resources:

          # TODO: Set memory limits when we've profiled the container for large

          # clusters, then set request = limit to keep this container in

          # guaranteed class. Currently, this container falls into the

          # "burstable" category so the kubelet doesn't backoff from restarting it.

          limits:

            memory: 170Mi

          requests:

            cpu: 100m

            memory: 70Mi

        livenessProbe:

          httpGet:

            path: /healthz-kubedns

            port: 8080

            scheme: HTTP

          initialDelaySeconds: 60

          timeoutSeconds: 5

          successThreshold: 1

          failureThreshold: 5

        readinessProbe:

          httpGet:

            path: /readiness

            port: 8081

            scheme: HTTP

          # we poll on pod startup for the Kubernetes master service and

          # only setup the /readiness HTTP server once that's available.

          initialDelaySeconds: 3

          timeoutSeconds: 5

        args:

        - --domain=cluster.local.

        - --dns-port=10053

        - --config-map=kube-dns

        - --kube-master-url=http://10.0.0.11:8080

        # This should be set to v=2 only after the new image (cut from 1.5) has

        # been released, otherwise we will flood the logs.

        - --v=0

        #__PILLAR__FEDERATIONS__DOMAIN__MAP__

        env:

        - name: PROMETHEUS_PORT

          value: "10055"

        ports:

        - containerPort: 10053

          name: dns-local

          protocol: UDP

        - containerPort: 10053

          name: dns-tcp-local

          protocol: TCP

        - containerPort: 10055

          name: metrics

          protocol: TCP

      - name: dnsmasq

        image: myhub.fdccloud.com/library/kube-dnsmasq-amd64:1.4

        livenessProbe:

          httpGet:

            path: /healthz-dnsmasq

            port: 8080

            scheme: HTTP

          initialDelaySeconds: 60

          timeoutSeconds: 5

          successThreshold: 1

          failureThreshold: 5

        args:

        - --cache-size=1000

        - --no-resolv

        - --server=127.0.0.1#10053

        #- --log-facility=-

        ports:

        - containerPort: 53

          name: dns

          protocol: UDP

        - containerPort: 53

          name: dns-tcp

          protocol: TCP

        # see: https://github.com/kubernetes/kubernetes/issues/29055 for details

        resources:

          requests:

            cpu: 150m

            memory: 10Mi

      - name: dnsmasq-metrics

        image: myhub.fdccloud.com/library/dnsmasq-metrics-amd64:1.0

        livenessProbe:

          httpGet:

            path: /metrics

            port: 10054

            scheme: HTTP

          initialDelaySeconds: 60

          timeoutSeconds: 5

          successThreshold: 1

          failureThreshold: 5

        args:

        - --v=2

        - --logtostderr

        ports:

        - containerPort: 10054

          name: metrics

          protocol: TCP

        resources:

          requests:

            memory: 10Mi

      - name: healthz

        image: myhub.fdccloud.com/library/exechealthz-amd64:1.2

        resources:

          limits:

            memory: 50Mi

          requests:

            cpu: 10m

            # Note that this container shouldn't really need 50Mi of memory. The

            # limits are set higher than expected pending investigation on #29688.

            # The extra memory was stolen from the kubedns container to keep the

            # net memory requested by the pod constant.

            memory: 50Mi

        args:

        - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null

        - --url=/healthz-dnsmasq

        - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null

        - --url=/healthz-kubedns

        - --port=8080

        - --quiet

        ports:

        - containerPort: 8080

          protocol: TCP

      dnsPolicy: Default  # Don't use cluster DNS.

編輯skydns-svc.yaml文件

# Copyright 2016 The Kubernetes Authors.

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

#     http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

 

# TODO - At some point, we need to rename all skydns-*.yaml.* files to kubedns-*.yaml.*

 

# Warning: This is a file generated from the base underscore template file: skydns-svc.yaml.base

 

apiVersion: v1

kind: Service

metadata:

  name: kube-dns

  namespace: kube-system

  labels:

    k8s-app: kube-dns

    kubernetes.io/cluster-service: "true"

    kubernetes.io/name: "KubeDNS"

spec:

  selector:

    k8s-app: kube-dns

  clusterIP: 10.254.230.254

  ports:

  - name: dns

    port: 53

    protocol: UDP

  - name: dns-tcp

    port: 53

    protocol: TCP

 

1.6.2 啓動

在master執行以下命令:

kubectl create -f  skydns-rc.yaml

kubectl create -f  skydns-svc.yaml

 

1.6.3修改node節點kubelet配置

查詢dns服務的clusterip。

kubectl get svc --namespace=kube-system

[root@k8s-matser ~]# kubectl get svc --namespace=kube-system

NAME                   CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE

kube-dns               10.254.230.254   <none>        53/UDP,53/TCP   7m

kubernetes-dashboard   10.254.249.6     <none>        80/TCP          4h

 

修改各node節點上的/etc/kubernetes/kubelet配置文件,增長以下行:

KUBELET_ARGS="--cluster_dns=10.254.230.254 --cluster_domain=cluster.local"

 

重啓各node節點kubelet:

systemctl restart kubelet

 

1.6.4驗證:

添加一個busybox的pod用於測試,busybox.yaml內容以下:

apiVersion: v1

kind: Pod

metadata:

  labels:

    name: busybox

    role: master

  name: busybox

spec:

  containers:

  - name: busybox

    image: myhub.fdccloud.com/library/busybox

    command:

    - sleep

    - "3600"

 

執行以下操做:

kubectl exec -it busybox sh

nslookup kubernetes

nslookup kubernetes.default.svc.cluster.local

若是能正常解析,則部署OK。

 

 

1.7  Kubernetes集成heapster

Heapster是kubernetes集羣監控工具。在1.2的時候,kubernetes的監控須要在node節點上運行cAdvisor做爲agent收集本機和容器的資源數據,包括cpu、內存、網絡、文件系統等。在新版的kubernetes中,cAdvisor被集成到kubelet中。經過netstat能夠查看到kubelet新開了一個4194的端口,這就是cAdvisor監聽的端口,如今咱們而後能夠經過http://<node-ip>:4194的方式訪問到cAdvisor。Heapster就是經過每一個node上的kubelet,也就是實際的cAdvisor上收集數據並彙總,保存到後端存儲中。

 

  Heapster支持多種後端存儲,包括influxDB,Elasticsearch,Kafka等,在這篇文檔裏,咱們使用influxDB做爲後端存儲來展現heapster的相關配置。須要說明的是,heapster依賴kubernetes dns配置。

1.7.1準備yaml配置文件

建立目錄heapster-influxdb,在目錄中建立如下文件

[root@k8s-master heapster-influxdb]# cat influxdb-grafana-controller.yaml

apiVersion: v1

kind: ReplicationController

metadata:

  labels:

    name: influxGrafana

  name: influxdb-grafana

  namespace: kube-system

spec:

  replicas: 1

  selector:

    name: influxGrafana

  template:

    metadata:

      labels:

        name: influxGrafana

    spec:

      containers:

      - name: influxdb

        image: docker.io/kubernetes/heapster_influxdb:v0.5

        volumeMounts:

        - mountPath: /data

          name: influxdb-storage

      - name: grafana

        image: docker.io/kubernetes/heapster_grafana:v2.6.0

        env:

          - name: INFLUXDB_SERVICE_URL

            value: http://monitoring-influxdb:8086

            # The following env variables are required to make Grafana accessible via

            # the kubernetes api-server proxy. On production clusters, we recommend

            # removing these env variables, setup auth for grafana, and expose the grafana

            # service using a LoadBalancer or a public IP.

          - name: GF_AUTH_BASIC_ENABLED

            value: "false"

          - name: GF_AUTH_ANONYMOUS_ENABLED

            value: "true"

          - name: GF_AUTH_ANONYMOUS_ORG_ROLE

            value: Admin

          - name: GF_SERVER_ROOT_URL

            value: /api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/

        volumeMounts:

        - mountPath: /var

          name: grafana-storage

      volumes:

      - name: influxdb-storage

        emptyDir: {}

      - name: grafana-storage

        emptyDir: {}

 

#######

[root@k8s-master heapster-influxdb]# cat grafana-service.yaml

apiVersion: v1

kind: Service

metadata:

  labels:

    kubernetes.io/cluster-service: 'true'

    kubernetes.io/name: monitoring-grafana

  name: monitoring-grafana

  namespace: kube-system

spec:

  # In a production setup, we recommend accessing Grafana through an external Loadbalancer

  # or through a public IP.

  # type: LoadBalancer

  ports:

  - port: 80

    targetPort: 3000

  selector:

    name: influxGrafana

#########

[root@k8s-master heapster-influxdb]# cat influxdb-service.yaml

apiVersion: v1

kind: Service

metadata:

  labels: null

  name: monitoring-influxdb

  namespace: kube-system

spec:

  ports:

  - name: http

    port: 8083

    targetPort: 8083

  - name: api

    port: 8086

    targetPort: 8086

  selector:

    name: influxGrafana

#######

[root@k8s-master heapster-influxdb]# cat heapster-controller.yaml

apiVersion: v1

kind: ReplicationController

metadata:

  labels:

    k8s-app: heapster

    name: heapster

    version: v6

  name: heapster

  namespace: kube-system

spec:

  replicas: 1

  selector:

    k8s-app: heapster

    version: v6

  template:

    metadata:

      labels:

        k8s-app: heapster

        version: v6

    spec:

      containers:

      - name: heapster

        image: docker.io/kubernetes/heapster:canary

        imagePullPolicy: Always

        command:

        - /heapster

        - --source=kubernetes:http://10.0.0.11:8080?inClusterConfig=false

        - --sink=influxdb:http://monitoring-influxdb:8086

########

[root@k8s-master heapster-influxdb]# cat heapster-service.yaml

apiVersion: v1

kind: Service

metadata:

  labels:

    kubernetes.io/cluster-service: 'true'

    kubernetes.io/name: Heapster

  name: heapster

  namespace: kube-system

spec:

  ports:

  - port: 80

    targetPort: 8082

  selector:

    k8s-app: heapster

 

1.7.2啓動

一個個的yaml文件建立太慢,能夠直接指定目錄來建立

[root@k8s-master ~]# kubectl create -f influxdb/

service "monitoring-grafana" created

replicationcontroller "heapster" created

service "heapster" created

replicationcontroller "influxdb-grafana" created

service "monitoring-influxdb" created

 

1.7.3 驗證

systemctl restart kube-apiserver.service

登陸dashboard,出現cpu和內存使用即成功

 

 

 

1.8 wordpress持久化實戰

1.8.1 準備兩個pv和pvc

準備配置文件

[root@k8s-master ~]# cat wordpres_nfs_pv.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv0001

  labels:

    type: nfs001

spec:

  capacity:

    storage: 10Gi

  accessModes:

    - ReadWriteMany

  persistentVolumeReclaimPolicy: Recycle

  nfs:

    path: "/data/web"

    server: 10.0.0.11

    readOnly: false

#######

[root@k8s-master ~]# cat  wordpress_nfs_pvc.yaml

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: nfs

spec:

  accessModes:

    - ReadWriteMany

  resources:

    requests:

      storage: 1Gi

########

[root@k8s-master ~]# cat mysql_nfs_pv.yaml

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv0002

  labels:

    type: nfs002

spec:

  capacity:

    storage: 20Gi

  accessModes:

    - ReadWriteMany

  persistentVolumeReclaimPolicy: Recycle

  nfs:

    path: "/data/db"

    server: 10.0.0.11

    readOnly: false

############

[root@k8s-master ~]# cat mysql_nfs_pvc.yaml

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: nfs2

spec:

  accessModes:

    - ReadWriteMany

  resources:

    requests:

      storage: 2Gi

 

1.8.2 建立pv和pvc

[root@k8s-master ~]# kubectl create -f  wordpress_nfs_pv.yaml

[root@k8s-master ~]# kubectl create -f  wordpress_nfs_pvc.yaml

[root@k8s-master ~]# kubectl create -f  mysql_nfs_pv.yaml

[root@k8s-master ~]# kubectl create -f  mysql_nfs_pvc.yaml

 

1.8.3 建立mysql rc和svc

[root@k8s-master ~]# cat mysql-rc.yaml

apiVersion: v1

kind: ReplicationController

metadata:

  name: mysql

spec:

  replicas: 1

  selector:

    app: mysql

  template:

    metadata:

      labels:

        app: mysql

    spec:

      containers:

      - name: mysql

        image: 10.0.0.11:5000/mysql:5.7

        ports:

        - containerPort: 3306

        volumeMounts:

        - name: nfs-vol2

          mountPath: /var/lib/mysql

        env:

        - name: MYSQL_ROOT_PASSWORD

          value: "somewordpress"

        - name: MYSQL_DATABASE

          value: "wordpress"

        - name: MYSQL_USER

          value: "wordpress"

        - name: MYSQL_PASSWORD

          value: "wordpress"

      volumes:

      - name: nfs-vol2

        persistentVolumeClaim:

          claimName: nfs2

#########

[root@k8s-master ~]# cat mysql-svc.yaml

apiVersion: v1

kind: Service

metadata:

  name: mysql

spec:

  clusterIP: 10.254.178.148

  ports:

    - port: 3306

  selector:

    app: mysql

#######

[root@k8s-master ~]# kubectl create -f mysql-rc.yaml

[root@k8s-master ~]# kubectl create -f mysql-svc.yaml

1.8.4 建立wordpress rc和svc

[root@k8s-master ~]# cat myweb-rc-nfs.yaml

apiVersion: v1

kind: ReplicationController

metadata:

  name: myweb

spec:

  replicas: 1

  selector:

    app: myweb

  template:

    metadata:

      labels:

        app: myweb

    spec:

      nodeName: '10.0.0.13'

      containers:

      - name: myweb

        image: 10.0.0.11:5000/wordpress:latest

        ports:

        - containerPort: 80

        volumeMounts:

        - name: nfs-vol

          mountPath: /var/www/html

        env:

        - name: WORDPRESS_DB_HOST

          value: '10.254.178.148'

        - name: WORDPRESS_DB_USER

          value: 'wordpress'

        - name: WORDPRESS_DB_PASSWORD

          value: 'wordpress'

      volumes:

      - name: nfs-vol

        persistentVolumeClaim:

          claimName: nfs

#############

[root@k8s-master ~]# cat myweb-svc.yaml

apiVersion: v1

kind: Service

metadata:

  name: myweb

spec:

  type: NodePort

  ports:

    - port: 80

      nodePort: 30001

  selector:

    app: myweb

#################

[root@k8s-master ~]# kubectl create -f myweb-rc-nfs.yaml

[root@k8s-master ~]# kubectl create -f myweb-svc.yaml

1.8.5  驗證

訪問http://10.0.0.12:30001安裝wordpress,刪除mysql或者myweb開頭的pod,wordpress依舊能訪問,數據不丟,即成功!

相關文章
相關標籤/搜索