1.Kubernetes概述
1.1 Kubernetes介紹
1.1.1 Kubernetes是什么及作用
Kubernetes(K8S)是Google在2014年發(fā)布的一個(gè)開源項(xiàng)目,用于自動(dòng)化容器化應(yīng)用程序的部署、擴(kuò)展和管理。
Kubernetes通常結(jié)合docker容器工作,并且整合多個(gè)運(yùn)行著docker容器的主機(jī)集群。
官網(wǎng)地址?Kubernetes
中文社區(qū) Kubernetes(k8s)中文文檔 目錄_Kubernetes中文社區(qū)
Kubernetes的目標(biāo)是讓部署容器化的應(yīng)用簡(jiǎn)單并且高效,Kubernetes一個(gè)核心特點(diǎn)就是能夠自主的管理容器來保證云平臺(tái)中的容器按照用戶的期望運(yùn)行。
以下是Kubernetes相關(guān)特性:
自動(dòng)包裝
根據(jù)資源需求和其他約束自動(dòng)放置容器,同時(shí)不會(huì)犧牲可用性,混合關(guān)鍵和最大努力的工作負(fù)載,以提高資源利用率并節(jié)省更多資源。
橫向縮放
使用簡(jiǎn)單的命令或 UI,或者根據(jù) CPU 的使用情況自動(dòng)調(diào)整應(yīng)用程序副本數(shù)。
自動(dòng)部署和回滾
Kubernetes 逐漸部署對(duì)應(yīng)用程序或其配置的更改,同時(shí)監(jiān)視應(yīng)用程序運(yùn)行狀況,以確保它不會(huì)同時(shí)終止所有實(shí)例。 如果出現(xiàn)問題,Kubernetes會(huì)為您恢復(fù)更改,利用日益增長(zhǎng)的部署解決方案的生態(tài)系統(tǒng)。
存儲(chǔ)編排
自動(dòng)安裝您所選擇的存儲(chǔ)系統(tǒng),無論是本地存儲(chǔ),如公有云提供商 GCP 或 AWS, 還是網(wǎng)絡(luò)存儲(chǔ)系統(tǒng) NFS,iSCSI, Gluster, Ceph, Cinder, 或 Flocker。
自我修復(fù)
重新啟動(dòng)失敗的容器,在節(jié)點(diǎn)不可用時(shí),替換和重新編排節(jié)點(diǎn)上的容器,終止不對(duì)用戶定義的健康檢查做出響應(yīng)的容器,并且不會(huì)在客戶端準(zhǔn)備投放之前將其通告給客戶端。
服務(wù)發(fā)現(xiàn)和負(fù)載均衡
不需要修改您的應(yīng)用程序來使用不熟悉的服務(wù)發(fā)現(xiàn)機(jī)制,Kubernetes 為容器提供了自己的 IP 地址和一組容器的單個(gè) DNS 名稱,并可以在它們之間進(jìn)行負(fù)載均衡。
密鑰和配置管理
部署和更新密鑰和應(yīng)用程序配置,不會(huì)重新編譯您的鏡像,不會(huì)在堆棧配置中暴露密鑰(secrets)。
批處理
除了服務(wù)之外,Kubernetes還可以管理您的批處理和 CI 工作負(fù)載,如果需要,替換出現(xiàn)故障的容器。
使用Kubernetes能做什么
Kubernetes是一個(gè)全新的基于容器技術(shù)的分布式架構(gòu)領(lǐng)先方案(源于Brog,是google十幾年經(jīng)驗(yàn)的結(jié)晶);
Kubernetes是一個(gè)開放的開發(fā)平臺(tái)(無侵入性,現(xiàn)有系統(tǒng)很容器遷移到Kubernetes上);
Kubernetes是一個(gè)完備的分布式系統(tǒng)支撐平臺(tái)(完善的集群管理能力)。
使用Kubernetes可以在物理或虛擬機(jī)的Kubernetes集群上運(yùn)行容器化應(yīng)用,Kubernetes能夠提供一個(gè)以容器為中心的基礎(chǔ)架構(gòu),滿足在生產(chǎn)環(huán)境中運(yùn)行應(yīng)用的一些常見需求,如:
多個(gè)進(jìn)程協(xié)同工作 存儲(chǔ)系統(tǒng)掛載 Distributing secrets 應(yīng)用健康檢測(cè) 應(yīng)用實(shí)例的復(fù)制 Pod自動(dòng)伸縮/擴(kuò)展 Naming and discovering 負(fù)載均衡 滾動(dòng)更新 資源監(jiān)控 日志訪問 調(diào)度應(yīng)用程序 提供認(rèn)證和授權(quán)
為什么使用Kubernetes
使用Kubernetes最直接的感受就是我們可以輕裝上陣的開發(fā)復(fù)雜的系統(tǒng)了;其次Kubernetes是在全面擁抱微服務(wù)架構(gòu)(微服務(wù)的核心就是將一個(gè)巨大的單體應(yīng)用拆分成很多小的互相連接的微服務(wù),一個(gè)微服務(wù)后面可能是多個(gè)實(shí)例副本在支撐,副本數(shù)量可以隨著系統(tǒng)負(fù)荷的變化而動(dòng)態(tài)調(diào)整);最后Kubernetes系統(tǒng)架構(gòu)具備超強(qiáng)的橫向擴(kuò)展能力。
1.1.2 Kubernetes快速入門
環(huán)境準(zhǔn)備
-
關(guān)閉CentOS防火墻
systemctl status firewalld.service ? 查看防火墻是否打開 ? systemctl stop firewalld.service ? ? 關(guān)閉防火墻 ? systemctl disable firewalld.service ? 永久關(guān)閉防火墻
-
安裝etcd和kubernetes軟件
yum install -y etcd kubernetes
-
啟動(dòng)服務(wù)
systemctl start etcd ? ==》 systemctl status etcd(查看) ? systemctl start docker ==》 systemctl status docker(查看)
如果docker啟動(dòng)失敗,請(qǐng)參考(vi /etc/sysconfig/selinux 把selinux后面的改為disabled,重啟機(jī)器(reboot -n),再重啟docker、啟動(dòng)服務(wù)就可以了)
systemctl start kube-apiserver ? systemctl start kube-controller-manager ? systemctl start kube-scheduler ? systemctl start kubelet ? systemctl start kube-proxy
配置(在/usr/local/k8s目錄下創(chuàng)建文件)
-
Tomcat配置
創(chuàng)建 mytomcat.rc.yaml 文件
apiVersion: v1 kind: ReplicationController metadata: ?name: mytomcat spec: ?replicas: 2 ?selector: ? app: mytomcat ?template: ? metadata: ? ?labels: ? ? app: mytomcat ? spec: ? ?containers: ? ? - name: mytomcat ? ? ? image: tomcat:7-jre7 ? ? ? ports: ? ? ? - containerPort: 8080
創(chuàng)建 mytomcat.svc.yaml 文件
apiVersion: v1 kind: Service metadata: ?name: mytomcat spec: ?type: NodePort ?ports: ? - port: 8080 ? ? nodePort: 30001 ?selector: ? app: mytomcat
執(zhí)行配置文件命令
kubectl create -f mytomcat.rc.yaml ? ==》 kubectl get pods(查看) ? kubectl create -f mytomcat.svc.yaml ==》 kubectl get svc(查看)
問題解決
瀏覽器出不來tom貓解決辦法
kubectl replace -f mytomcat.rc.yaml ? kubectl delete svc ? kubectl delete svc --all ? kubectl create -f mytomcat.svc.yaml
docker pull失敗
解決方案1 ? 1、yum install rhsm -y yum install *rhsm* ? 2、docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest ? 如果以上兩步解決問題了,那么就不需要在執(zhí)行下面操作 ? 3、docker search pod-infrastructure ? 4、docker pull docker.io/tianyebj/pod-infrastructure ? 5、docker tag tianyebj/pod-infrastructure 192.168.1.83:5000/pod-infrastructure ? 6、docker push 192.168.1.83:5000/pod-infrastructure ? 7、vi /etc/kubernetes/kubelet 修改 KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=192.168.1.83:5000/pod-infrastructure:latest" ? 8、重啟服務(wù) systemctl restart kube-apiserver systemctl restart kube-controller-manager systemctl restartkube-scheduler systemctl restart kubelet systemctl restart kube-proxy
解決方案2 ? 1、docker pull kubernetes/pause ? 2、docker tag docker.io/kubernetes/pause:latest 192.168.1.83:5000/google_containers/pause-amd64.3.0 ? 3、docker push 192.168.1.83:5000/google_containers/pause-amd64.3.0 ? 4、vi /etc/kubernetes/kubelet 配置為 KUBELET_ARGS="--pod_infra_container_image=192.168.187.137:5000/google_containers/pause-amd64.3.0" ? 5、重啟kubelet服務(wù) systemctl restart kubelet
發(fā)現(xiàn)缺少/etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt
解決:
yum install *rhsm*
?
安裝完成后,執(zhí)行一下
docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
?
如果依然報(bào)錯(cuò),可參考下面的方案:
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm
rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee /etc/rhsm/ca/redhat-uep.pemsystemctl restart docker ? 然后重啟一下
?
kubectl describe pod?pod名稱 ? 查看pod詳情
?
kubectl logs -f pod名稱 ?? 查看pod日志
外部網(wǎng)不能訪問
在搭建好的k8s集群內(nèi)創(chuàng)建的容器,只能在其所在的節(jié)點(diǎn)上curl可訪問,但是在其他任何主機(jī)上無法訪問容器占用的端口
解決方案: 1、vim /etc/sysctl.conf ? 2、最后面加上這一行:net.ipv4.ip_forward=1
解決 kubectl get pods 時(shí)No resources found
1、vim /etc/kubernetes/apiserver ? 2、找到”KUBE_ADMISSION_CONTROL="-admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota",去掉ServiceAccount,保存退出 ? 3、systemctl restart kube-apiserver 重啟此服務(wù)
瀏覽測(cè)試
1.2 Kubernetes基本架構(gòu)與常用術(shù)語
Kubernetes集群包含有節(jié)點(diǎn)代理kubelet和Master組件(APIs, scheduler, etc),一切都基于分布式的存儲(chǔ)系統(tǒng)。下面這張圖是Kubernetes的架構(gòu)圖。
?在這張系統(tǒng)架構(gòu)圖中,我們把服務(wù)分為運(yùn)行在工作節(jié)點(diǎn)上的服務(wù)和組成集群級(jí)別控制板的服務(wù)。
Kubernetes節(jié)點(diǎn)有運(yùn)行應(yīng)用容器必備的服務(wù),而這些都是受Master的控制。
每次個(gè)節(jié)點(diǎn)上當(dāng)然都要運(yùn)行Docker。Docker來負(fù)責(zé)所有具體的映像下載和容器運(yùn)行。
Kubernetes主要由以下幾個(gè)核心組件組成:
etcd 保存了整個(gè)集群的狀態(tài);
apiserver 提供了資源操作的唯一入口,并提供認(rèn)證、授權(quán)、訪問控制、API注冊(cè)和發(fā)現(xiàn)等機(jī)制;
controller manager 負(fù)責(zé)維護(hù)集群的狀態(tài),比如故障檢測(cè)、自動(dòng)擴(kuò)展、滾動(dòng)更新等;
scheduler 負(fù)責(zé)資源的調(diào)度,按照預(yù)定的調(diào)度策略將Pod調(diào)度到相應(yīng)的機(jī)器上;
kubelet 負(fù)責(zé)維護(hù)容器的生命周期,同時(shí)也負(fù)責(zé)Volume(CVI)和網(wǎng)絡(luò)(CNI)的管理;
Container runtime 負(fù)責(zé)鏡像管理以及Pod和容器的真正運(yùn)行(CRI);
kube-proxy 負(fù)責(zé)為Service提供cluster內(nèi)部的服務(wù)發(fā)現(xiàn)和負(fù)載均衡;
除了核心組件,還有一些推薦的Add-ons:
kube-dns 負(fù)責(zé)為整個(gè)集群提供DNS服務(wù)
Ingress Controller 為服務(wù)提供外網(wǎng)入口
Heapster 提供資源監(jiān)控
Dashboard 提供GUI
Federation 提供跨可用區(qū)的集群
Fluentd-elasticsearch 提供集群日志采集、存儲(chǔ)與查詢
Kubernetes設(shè)計(jì)理念和功能其實(shí)就是一個(gè)類似Linux的分層架構(gòu)
核心層:Kubernetes最核心的功能,對(duì)外提供API構(gòu)建高層的應(yīng)用,對(duì)內(nèi)提供插件式應(yīng)用執(zhí)行環(huán)境
應(yīng)用層:部署(無狀態(tài)應(yīng)用、有狀態(tài)應(yīng)用、批處理任務(wù)、集群應(yīng)用等)和路由(服務(wù)發(fā)現(xiàn)、DNS解析等)
管理層:系統(tǒng)度量(如基礎(chǔ)設(shè)施、容器和網(wǎng)絡(luò)的度量),自動(dòng)化(如自動(dòng)擴(kuò)展、動(dòng)態(tài)Provision等)以及策略
管理(RBAC、Quota、PSP、NetworkPolicy等)
接口層:kubectl命令行工具、客戶端SDK以及集群聯(lián)邦
生態(tài)系統(tǒng):在接口層之上的龐大容器集群管理調(diào)度的生態(tài)系統(tǒng),可以劃分為兩個(gè)范疇
? ? ? ?Kubernetes外部:日志、監(jiān)控、配置管理、CI、CD、Workflflow、FaaS、OTS應(yīng)用、ChatOps等
? ? ? ? ? ? ? Kubernetes內(nèi)部:CRI、CNI、CVI、鏡像倉庫、Cloud Provider、集群自身的配置和管理等
1.2.1 Cluster
Cluster是計(jì)算、存儲(chǔ)和網(wǎng)絡(luò)資源的集合,Kubernetes利用這些資源運(yùn)行各種基于容器的應(yīng)用.
Kubernetes Cluster由Master和Node組成,節(jié)點(diǎn)上運(yùn)行著若干Kubernetes服務(wù)
1.2.2 Master
Master主要職責(zé)是調(diào)度,即決定將應(yīng)用放在哪運(yùn)行。Master運(yùn)行Linux系統(tǒng),可以是物理機(jī)或虛擬機(jī)。 Master是Kubernetes Cluster的大腦,運(yùn)行著的Daemon服務(wù)包括kube-apiserver、kube-scheduler、kuber-controller-manager、etcd和Pod網(wǎng)絡(luò)
API Serer(kube-apiserver)
API Server 提供HTTP/HTTPS RESTful API,即Kubernetes API.是Kubernetes里所有資源的CRUD等操作的唯一入口,也是集群控制的入口進(jìn)程
Scheduler(kube-scheduler)
Scheduler負(fù)責(zé)資源調(diào)度的里程,簡(jiǎn)單說,它決定將Pod放在哪個(gè)Node上運(yùn)行
Controller Manager(kube-controller-manager)
所有資源對(duì)象的自動(dòng)化控制中心。Controller Manager負(fù)責(zé)管理Cluster各種資源,保證資源處于預(yù)期的狀態(tài)。Controller Manager有多種,如replication controller、endpoints controller、namespacecontroller、serviceaccounts controller等。
不同的controller管理不同的資源,如replication controller管理Deployment、StatefulSet、DaemonSet的生命周期,namespace controller管理Namespace資源
etcd
etcd負(fù)責(zé)保存Kubernetes Cluster的配置信息和各種資源的狀態(tài)信息。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),etcd會(huì)快速地通知Kubernetes相關(guān)組件
Pod網(wǎng)絡(luò)
Pod要能夠相互通信,Kubernetes Cluster必須部署Pod網(wǎng)絡(luò),flflannel是其中一個(gè)可選方案。
1.2.2 Node
除了Master,Kubernetes集群中的其它機(jī)器被稱為Node節(jié)點(diǎn)。Node職責(zé)是運(yùn)行容器應(yīng)用,Node由Master管理,Node負(fù)責(zé)監(jiān)控并匯報(bào)容器的狀態(tài),同時(shí)根據(jù)Master的要求管理容器的生命周期。Node也運(yùn)行在Linux系統(tǒng),可以是物理機(jī)或虛擬機(jī)。
每個(gè)Node節(jié)點(diǎn)上都運(yùn)行著以下一組關(guān)鍵進(jìn)程
kubelet
負(fù)責(zé)Pod對(duì)應(yīng)的容器的創(chuàng)建、啟動(dòng)等任務(wù),同時(shí)與Master節(jié)點(diǎn)密切協(xié)作,實(shí)現(xiàn)集群管理的基本功能
kube-proxy
實(shí)現(xiàn)Kubernetes Service的通信與負(fù)載均衡機(jī)制的重要組件
Docker Enginer
Docker引擎,負(fù)責(zé)本機(jī)的容器創(chuàng)建和管理工作
1.2.3 Pod
Pod是Kubernetes的最小單元,也是最重要和最基本的概念。每一個(gè)Pod包含一個(gè)或多個(gè)容器,Pod的容器會(huì)作為一個(gè)整體被Master調(diào)到一個(gè)Node上運(yùn)行。Kubenetes為每個(gè)Pod都分配了唯一的IP地址,稱為PodIP,一個(gè)Pod里的多個(gè)容器共享PodIP地址。在Kubernetes里,一個(gè)Pod里的容器與另外主機(jī)上的Pod容器能夠直接通信。
1.2.4 Service
Kubernetes Service定義了外界訪問一組特定Pod的方式,Service有自己的IP和端口,Service為Pod提供了負(fù)載均衡。它也是Kubernetes最核心的資源對(duì)象之一,每個(gè)Service其實(shí)就是我們經(jīng)常提起的微服務(wù)架構(gòu)中的一個(gè)"微服務(wù)"。
1.2.5 Replication Controller
Replication Controller(簡(jiǎn)稱RC)是Kubernetes系統(tǒng)中的核心概念之一,它其實(shí)是定義了一個(gè)期望的場(chǎng)景,即聲明某種Pod的副本數(shù)量在任意時(shí)刻都符合某個(gè)預(yù)期值,所以RC的定義包括如下幾個(gè)部分
Pod期待的副本數(shù)(replicas)
用于篩選目標(biāo)Pod的Label Selector
當(dāng)Pod的副本數(shù)量小于預(yù)期數(shù)量時(shí),用于創(chuàng)建新Pod的Pod模板(template)
以下是總結(jié)的RC的一些特性與作用
在大多數(shù)情況下,我們通過定義一個(gè)RC實(shí)現(xiàn)Pod的創(chuàng)建過程及副本數(shù)量的自動(dòng)控制
RC里包括完整的Pod定義模板
RC通過Label Selector機(jī)制實(shí)現(xiàn)對(duì)Pod副本的自動(dòng)控制
通過改變RC里的Pod副本數(shù)量,可以實(shí)現(xiàn)Pod的擴(kuò)容或縮容功能
通過改變RC里Pod模板中鏡像版本,可以實(shí)現(xiàn)Pod的滾動(dòng)升級(jí)功能
2.Kubernetes集群
Kubernetes用于協(xié)調(diào)高度可用的計(jì)算機(jī)集群,這些計(jì)算機(jī)群集被連接作為單個(gè)單元工作。Kubernetes 在一個(gè)集群上以更有效的方式自動(dòng)分發(fā)和調(diào)度容器應(yīng)用程序。Kubernetes集群由兩種類型的資源組成:
-
Master是集群的調(diào)度節(jié)點(diǎn)
-
Nodes是應(yīng)用程序?qū)嶋H運(yùn)行的工作節(jié)點(diǎn)
接下來為大家講解一下如何快速部署一套Kubernetes集群,K8S集群部署有幾種方式:kubeadm、minikube和二進(jìn)制包。前兩者屬于自動(dòng)部署,簡(jiǎn)化部署操作,我們這里強(qiáng)烈推薦初學(xué)者使用二進(jìn)制包部署,因?yàn)樽詣?dòng)部署屏蔽了很多細(xì)節(jié),使得對(duì)各個(gè)模塊感知很少,非常不利用學(xué)習(xí)。
2.1環(huán)境準(zhǔn)備與規(guī)劃
-
推薦配置2核2G
Docker version 17.05.0-ce
角色 | IP | 組件 |
---|---|---|
master | 192.168.126.140 | etcd、kube-apiserver、kube-controller-manager、 kube-scheduler、docker |
node01 | 192.168.126.141 | kube-proxy、kubelet、docker |
node02 | 192.168.126.142 | kube-proxy、kubelet、docker |
-
查看默認(rèn)防火墻狀態(tài)(關(guān)閉后顯示not running ,開啟后顯示 running)
firewall-cmd --state
-
關(guān)閉防火墻
systemctl stop fifirewalld.service
-
禁止firewall開機(jī)啟動(dòng)
systemctl disable firewalld.service
-
獲取Kubernetes二進(jìn)制包
kubernetes/CHANGELOG-1.9.md at master · kubernetes/kubernetes · GitHub
頁面表格中找到Server Binaries中的kubernetes-server-linux-amd64.tar.gz文件,下載到本地。
該壓縮包中包括了k8s需要運(yùn)行的全部服務(wù)程序文件
2.2 Master安裝
2.2.1 Docker安裝
yum update
(1)設(shè)置yum源
vi /etc/yum.repos.d/docker.repo ? [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg
(2)安裝docker
yum install docker-engine -y
(3)安裝后查看docker版本
docker -v
2.2.2 etcd服務(wù)
etcd做為Kubernetes集群的主要服務(wù),在安裝Kubernetes各服務(wù)前需要首先安裝和啟動(dòng)。
-
下載etcd二進(jìn)制文件
Releases · etcd-io/etcd · GitHub
-
上傳到master
可以使用lrzsz,如果沒有安裝,可以通過yum進(jìn)行安裝 yum install lrzsz
上傳到??/usr/local/k8s? 目錄并解壓
tar -zxvf etcd-v3.3.9-linux-amd64.tar.gz?
-
進(jìn)入 etcd-v3.3.9-linux-amd64 目錄 將etcd和etcdctl文件復(fù)制到/usr/bin目錄
cp etcd etcdctl /usr/bin
-
配置systemd服務(wù)文件vi /usr/lib/systemd/system/etcd.service
[Unit] Description=Etcd Server After=network.target [Service] Type=simple EnvironmentFile=-/etc/etcd/etcd.conf WorkingDirectory=/var/lib/etcd/ ExecStart=/usr/bin/etcd Restart=on-failure [Install] WantedBy=multi-user.target
-
啟動(dòng)與測(cè)試etcd服務(wù)
systemctl daemon-reload systemctl enable etcd.service mkdir -p /var/lib/etcd/ systemctl start etcd.service systemctl status etcd.service etcdctl cluster-health
2.2.3 kube-apiserver服務(wù)
/usr/local/k8s 目錄下 上傳 kubernetes-server-linux-amd64.tar.gz 文件并解壓
tar -zxvf kubernetes-server-linux-amd64.tar.gz
解壓后進(jìn)入到 kubernetes/server/bin 將kube-apiserver、kube-controller-manager、kube-scheduler以及管理要使用的kubectl二進(jìn)制命令文件放到/usr/bin目錄,即完成這幾個(gè)服務(wù)的安裝。
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/bin/
下面是對(duì)kube-apiserver服務(wù)進(jìn)行配置
編輯systemd服務(wù)文件 vi /usr/lib/systemd/system/kube-apiserver.service
[Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes After=etcd.service Wants=etcd.service [Service] EnvironmentFile=/etc/kubernetes/apiserver ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS Restart=on-failure Type=notify [Install] WantedBy=multi-user.target
配置文件
創(chuàng)建目錄:mkdir /etc/kubernetes
vi /etc/kubernetes/apiserver
KUBE_API_ARGS="--storage-backend=etcd3 --etcd-servers=http://127.0.0.1:2379 --insecure-bind-address=0.0.0.0 --insecure-port=8080 --service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535 --admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,Defaul tStorageClass,ResourceQuota --logtostderr=true --log-dir=/var/log/kubernetes --v=2"
2.2.4 kube-controller-manager服務(wù)
kube-controller-manager服務(wù)依賴于kube-apiserver服務(wù):
配置systemd服務(wù)文件:vi /usr/lib/systemd/system/kube-controller-manager.service
[Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=kube-apiserver.service Requires=kube-apiserver.service [Service] EnvironmentFile=-/etc/kubernetes/controller-manager ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
配置文件: vi /etc/kubernetes/controller-manager
KUBE_CONTROLLER_MANAGER_ARGS="--master=http://192.168.1.83:8080 --logtostderr=true --log-dir=/var/log/kubernetes --v=2"
2.2.5 kube-scheduler服務(wù)
kube-scheduler服務(wù)也依賴于kube-apiserver服務(wù)。
配置systemd服務(wù)文件:vi /usr/lib/systemd/system/kube-scheduler.service
[Unit] Description=Kubernetes Scheduler ? Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=kube-apiserver.service Requires=kube-apiserver.service ? [Service] EnvironmentFile=-/etc/kubernetes/scheduler ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS Restart=on-failure LimitNOFILE=65536 ? [Install] WantedBy=multi-user.target
配置文件:vi /etc/kubernetes/scheduler
KUBE_SCHEDULER_ARGS="--master=http://192.168.1.83:8080 --logtostderr=true --log-dir=/var/log/kubernetes --v=2"
2.2.6 啟動(dòng)
完成以上配置后,按順序啟動(dòng)服務(wù)
systemctl daemon-reload systemctl enable etcd systemctl start etcd systemctl status etcd systemctl enable docker systemctl start docker systemctl status docker systemctl enable kube-apiserver.service systemctl start kube-apiserver.service systemctl status kube-apiserver.service systemctl enable kube-controller-manager.service systemctl start kube-controller-manager.service systemctl status kube-controller-manager systemctl enable kube-scheduler.service systemctl start kube-scheduler.service systemctl status kube-scheduler.service
檢查每個(gè)服務(wù)的健康狀態(tài):
systemctl status kube-apiserver.service systemctl status kube-controller-manager.service systemctl status kube-scheduler.service
2.3 Node1 安裝
在Node1節(jié)點(diǎn)上,以同樣的方式把從壓縮包中解壓出的二進(jìn)制文件kubelet kube-proxy放到/usr/bin目錄中。
/usr/local/k8s 目錄 進(jìn)入到這個(gè)目錄里面:
cd kubernetes/server/bin
復(fù)制:
cp kubelet kube-proxy /usr/bin
在Node1節(jié)點(diǎn)上需要預(yù)先安裝docker,請(qǐng)參考Master上Docker的安裝,并啟動(dòng)Docker
yum install docker-engine -y
systemctl enable docker
systemctl start docker
systemctl status docker
2.3.1 kubelet服務(wù)
配置systemd服務(wù)文件:vi /usr/lib/systemd/system/kubelet.service
[Unit] Description=Kubernetes Kubelet Server Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=docker.service Requires=docker.service [Service] WorkingDirectory=/var/lib/kubelet EnvironmentFile=-/etc/kubernetes/kubelet ExecStart=/usr/bin/kubelet $KUBELET_ARGS Restart=on-failure KillMode=process [Install] WantedBy=multi-user.target
mkdir -p /var/lib/kubelet
配置文件:vi /etc/kubernetes/kubelet
KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kubeconfig --hostname-override=192.168.1.83 --logtostderr=false --log-dir=/var/log/kubernetes --v=2 --fail-swap-on=false"
用于kubelet連接Master Apiserver的配置文件
vi /etc/kubernetes/kubeconfifig
apiVersion: v1 kind: Config clusters: - cluster: server: http://192.168.1.83:8080 name: local contexts: - context: cluster: local name: mycontext current-context: mycontext
2.3.2 kube-proxy 服務(wù)
kube-proxy服務(wù)依賴于network服務(wù),所以一定要保證network服務(wù)正常,如果network服務(wù)啟動(dòng)失敗,常見解決方
案有以下幾中:
1.和 NetworkManager 服務(wù)有沖突,這個(gè)好解決,直接關(guān)閉 NetworkManger 服務(wù)就好了,service NetworkManager stop,并且禁止開機(jī)啟動(dòng) chkconfig NetworkManager off 。之后重啟就好了 2.和配置文件的MAC地址不匹配,這個(gè)也好解決,使用ip addr(或ifconfig)查看mac地址,將/etc/sysconfig/network-scripts/ifcfg-xxx中的HWADDR改為查看到的mac地址 3.設(shè)定開機(jī)啟動(dòng)一個(gè)名為NetworkManager-wait-online服務(wù),命令為:systemctl enable NetworkManager-wait-online.service 4.查看/etc/sysconfig/network-scripts下,將其余無關(guān)的網(wǎng)卡位置文件全刪掉,避免不必要的影響,即只留一個(gè)以ifcfg開頭的文件
配置systemd服務(wù)文件:vi /usr/lib/systemd/system/kube-proxy.service
[Unit] Description=Kubernetes Kube-proxy Server Documentation=https://github.com/GoogleCloudPlatform/kubernetes After=network.service Requires=network.service [Service] EnvironmentFile=/etc/kubernetes/proxy ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS Restart=on-failure LimitNOFILE=65536 KillMode=process [Install] WantedBy=multi-user.target
配置文件:vi /etc/kubernetes/proxy
KUBE_PROXY_ARGS="--master=http://192.168.1.83:8080 --hostname override=192.168.1.84 --logtostderr=true --log-dir=/var/log/kubernetes --v=2"
2.3.3 啟動(dòng)
systemctl daemon-reload
systemctl start docker
systemctl status dockersystemctl enable kubelet
systemctl start kubelet
systemctl status kubelet
systemctl enable kube-proxy
systemctl start kube-proxy
systemctl status kube-proxy
2.4 Node2 安裝
參考Node1安裝,注意修改IP
?
?
?
?
?
?
2.5 健康檢查與示例測(cè)試
-
查看集群狀態(tài)
kubectl get nodes
-
查看master集群組件狀態(tài)
kubectl get cs
/usr/local/k8s 下創(chuàng)建文件? ?nginx-rc.yaml? ? ?nginx-svc.yaml
-
nginx-rc.yaml
apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 3 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
kubectl create -f nginx-rc.yaml?
kubectl create -f nginx-svc.yaml
-
nginx-svc.yaml
apiVersion: v1 kind: Service metadata: name: nginx spec: type: NodePort ports: - port: 80 nodePort: 33333 selector: app: nginx
-
查看pod
kubectl get pods
-
查看具體pod詳情
kubectl describe pods?nginx-ml7qc
?私有倉庫搭建
docker pull registry
docker run -di --name=registry -p 5000:5000 registry
修改daemon.json {"insecure-registries":["192.168.126.148:5000"]}
重啟docker服務(wù) systemctl restart docker
總結(jié)
1.K8S架構(gòu)和組件
1.1 Master
-
Kubernetes API Server
作為Kubernetes系統(tǒng)的入口,其封裝了核心對(duì)象的增刪改查操作,以RESTful API接口方式提供給外部客戶和內(nèi)部組件調(diào)用。維護(hù)的REST對(duì)象持久化到Etcd中存儲(chǔ)。
-
Kubernetes Scheduler 為新建立的Pod進(jìn)行節(jié)點(diǎn)(node)選擇(即分配機(jī)器),負(fù)責(zé)集群的資源調(diào)度。組件抽離,可以方便替換成其他調(diào)度器。
-
Kubernetes Controller
負(fù)責(zé)執(zhí)行各種控制器,目前已經(jīng)提供了很多控制器來保證Kubernetes的正常運(yùn)行。
-
Replication Controller
管理維護(hù)Replication Controller,關(guān)聯(lián)Replication Controller和Pod,保證Replication Controller定義的副本數(shù)量與實(shí)際運(yùn)行Pod數(shù)量一致。
1.2 Node
-
Kubelet
負(fù)責(zé)管控容器,Kubelet會(huì)從Kubernetes API Server接收Pod的創(chuàng)建請(qǐng)求,啟動(dòng)和停止容器,監(jiān)控容器運(yùn)行狀態(tài)并匯報(bào)給Kubernetes API Server。
-
Kubernetes Proxy
負(fù)責(zé)為Pod創(chuàng)建代理服務(wù),Kubernetes Proxy會(huì)從Kubernetes API Server獲取所有的Service信息,并根據(jù)Service的信息創(chuàng)建代理服務(wù),實(shí)現(xiàn)Service到Pod的請(qǐng)求路由和轉(zhuǎn)發(fā),從而實(shí)現(xiàn)Kubernetes層級(jí)的虛擬轉(zhuǎn)發(fā)網(wǎng)絡(luò)。
-
Docker
Node上需要運(yùn)行容器服務(wù)
2.K8S集群搭建常見問題
- 解決 kubectl get pods時(shí)No resources found問題
1、vim /etc/kubernetes/apiserver
2、找到”KUBE_ADMISSION_CONTROL="- admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota",去掉ServiceAccount,保存退出。
3、systemctl restart kube-apiserver 重啟此服務(wù)
pull 失敗
解決方案1
1、yum install rhsm -y? ? ? ? ? ? ?yum install *rhsm*
2、docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
如果以上兩步解決問題了,那么就不需要在執(zhí)行下面操作
3、docker search pod-infrastructure
4、docker pull docker.io/tianyebj/pod-infrastructure
5、docker tag tianyebj/pod-infrastructure 192.168.126.143:5000/pod-infrastructure
6、docker push 192.168.126.143:5000/pod-infrastructure
7、vi /etc/kubernetes/kubelet
修改 KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=192.168.126.143:5000/pod- infrastructure:latest"
8、重啟服務(wù)
????????????????systemctl restart kube-apiserver
????????????????systemctl restart kube-controller-manager
????????????????systemctl restart kube-scheduler
????????????????systemctl restart kubelet systemctl
????????????????restart kube-proxy
-
解決方案2
1、docker pull kubernetes/pause
2、docker tag docker.io/kubernetes/pause:latest 192.168.126.143:5000/google_containers/pause-amd64.3.0
3、docker push 192.168.126.143:5000/google_containers/pause-amd64.3.0
4、vi /etc/kubernetes/kubelet配置為
KUBELET_ARGS="--pod_infra_container_image=192.168.126.143:5000/google_containers/pause-amd64.3.0"
5、重啟kubelet服務(wù) systemctl restart kubelet
3.常用命令
-
獲取當(dāng)前命名空間下的容器
kubectl get pods
-
獲取所有容器l列表
kubectl get all
-
創(chuàng)建 容器
kubectl create -f kubernate-pvc.yaml
-
刪除容器
kubectl delete pods/test-pd 或者 kubectl delete -f rc-nginx.yaml
-
查看指定pod跑在哪個(gè)node上
kubectl get pod /test-pd -o wide
-
查看容器日志
Kubectl logs nginx-8586cf59-mwwtc
kubectl describe pods?nginx-8586cf59-mwwtc
-
進(jìn)入容器終端命令
kubectl exec -it nginx-8586cf59-mwwtc /bin/bash
-
一個(gè)Pod里含有多個(gè)容器 用--container or -c 參數(shù)。
例如:假如這里有個(gè)Pod名為my-pod,這個(gè)Pod有兩個(gè)容器,分別名為main-app 和 helper-app,下面的命令將打開到main-app的shell的容器里。
kubectl exec -it my-pod --container main-app -- /bin/bash
-
容器詳情列表
kubectl describe pod/mysql- m8rbl
-
查看容器狀態(tài)
kubectl get svc
容器化進(jìn)階Kubernetes核心技術(shù)
1 Pod 詳解
Pod是Kubernetes的最重要概念,每一個(gè)Pod都有一個(gè)特殊的被稱為”根容器“的Pause容器。Pause容器對(duì)應(yīng)的鏡像屬于Kubernetes平臺(tái)的一部分,除了Pause容器,每個(gè)Pod還包含一個(gè)或多個(gè)緊密相關(guān)的用戶業(yè)務(wù)容器。
?
-
Pod vs 應(yīng)用
每個(gè)Pod都是應(yīng)用的一個(gè)實(shí)例,有專用的IP
-
Pod vs 容器
一個(gè)Pod可以有多個(gè)容器,彼此間共享網(wǎng)絡(luò)和存儲(chǔ)資源,每個(gè)Pod 中有一個(gè)Pause容器保存所有的容器狀態(tài),通過管理pause容器, 達(dá)到管理pod中所有容器的效果
-
Pod vs 節(jié)點(diǎn)
同一個(gè)Pod中的容器總會(huì)被調(diào)度到相同Node節(jié)點(diǎn),不同節(jié)點(diǎn)間Pod的通信基于虛擬二層網(wǎng)絡(luò)技術(shù)實(shí)現(xiàn)
-
Pod vs Pod
普通的Pod和靜態(tài)Pod
1.1 Pod 的定義
下面是yaml文件定義的Pod的完整內(nèi)容
apiVersion: v1 //版本 kind: Pod //類型,pod metadata: //元數(shù)據(jù) name: string //元數(shù)據(jù),pod的名字 namespace: string //元數(shù)據(jù),pod的命名空間 labels: //元數(shù)據(jù),標(biāo)簽列表 - name: string //元數(shù)據(jù),標(biāo)簽的名字 annotations: //元數(shù)據(jù),自定義注解列表 - name: string //元數(shù)據(jù),自定義注解名字 spec: //pod中容器的詳細(xì)定義 containers: //pod中的容器列表,可以有多個(gè)容器 - name: string //容器的名稱 image: string //容器中的鏡像 imagesPullPolicy: [Always|Never|IfNotPresent] //獲取鏡像的策略,默認(rèn)值為Always,每次都嘗試重新下載鏡像 command: [string] //容器的啟動(dòng)命令列表(不配置的話使用鏡像內(nèi)部的命令) args: [string] //啟動(dòng)參數(shù)列表 workingDir: string //容器的工作目錄 volumeMounts: //掛載到到容器內(nèi)部的存儲(chǔ)卷設(shè)置 - name: string mountPath: string //存儲(chǔ)卷在容器內(nèi)部Mount的絕對(duì)路徑 readOnly: boolean //默認(rèn)值為讀寫 ports: //容器需要暴露的端口號(hào)列表 - name: string containerPort: int //容器要暴露的端口 hostPort: int //容器所在主機(jī)監(jiān)聽的端口(容器暴露端口映射到宿主機(jī)的端口,設(shè)置hostPort時(shí)同一臺(tái)宿主機(jī)將不能再啟動(dòng)該容器的第2份副本) protocol: string //TCP和UDP,默認(rèn)值為TCP env: //容器運(yùn)行前要設(shè)置的環(huán)境列表 - name: string value: string resources: limits: //資源限制,容器的最大可用資源數(shù)量 cpu: Srting memory: string requeste: //資源限制,容器啟動(dòng)的初始可用資源數(shù)量 cpu: string memory: string livenessProbe: //pod內(nèi)容器健康檢查的設(shè)置 exec: command: [string] //exec方式需要指定的命令或腳本 httpGet: //通過httpget檢查健康 path: string port: number host: string scheme: Srtring httpHeaders: - name: Stirng value: string tcpSocket: //通過tcpSocket檢查健康 port: number initialDelaySeconds: 0 //首次檢查時(shí)間 timeoutSeconds: 0 //檢查超時(shí)時(shí)間 periodSeconds: 0 //檢查間隔時(shí)間 successThreshold: 0 failureThreshold: 0 securityContext: //安全配置 privileged: falae restartPolicy: [Always|Never|OnFailure] //重啟策略,默認(rèn)值為Always nodeSelector: object //節(jié)點(diǎn)選擇,表示將該P(yáng)od調(diào)度到包含這些label的Node上,以key:value格式指定 imagePullSecrets: - name: string hostNetwork: false //是否使用主機(jī)網(wǎng)絡(luò)模式,棄用Docker網(wǎng)橋,默認(rèn)否 volumes: //在該pod上定義共享存儲(chǔ)卷列表 - name: string emptyDir: {} //是一種與Pod同生命周期的存儲(chǔ)卷,是一個(gè)臨時(shí)目錄,內(nèi)容為空 hostPath: //Pod所在主機(jī)上的目錄,將被用于容器中mount的目錄 path: string secret: //類型為secret的存儲(chǔ)卷 secretName: string item: - key: string path: string configMap: //類型為configMap的存儲(chǔ)卷 name: string items: - key: string path: string
1.2 Pod的基本用法
在kubernetes中對(duì)運(yùn)行容器的要求為:容器的主程序需要一直在前臺(tái)運(yùn)行,而不是后臺(tái)運(yùn)行。應(yīng)用需要改造成前臺(tái)運(yùn)行的方式。如果我們創(chuàng)建的Docker鏡像的啟動(dòng)命令是后臺(tái)執(zhí)行程序,則在kubelet創(chuàng)建包含這個(gè)容器的pod之后運(yùn)行完該命令,即認(rèn)為Pod已經(jīng)結(jié)束,將立刻銷毀該P(yáng)od。如果為該P(yáng)od定義了RC,則創(chuàng)建、銷毀會(huì)陷入一個(gè)無限循環(huán)的過程中。
Pod可以由1個(gè)或多個(gè)容器組合而成。
-
由一個(gè)容器組成的Pod示例
# 一個(gè)容器組成的Pod apiVersion: v1 kind: Pod metadata: name: mytomcat labels: name: mytomcat spec: containers: - name: mytomcat image: tomcat ports: - containerPort: 8000
-
由兩個(gè)為緊耦合的容器組成的Pod示例
#兩個(gè)緊密耦合的容器 apiVersion: v1 kind: Pod metadata: name: myweb labels: name: tomcat-redis spec: containers: - name: tomcat image: tomcat ports: - containerPort: 8080 - name: redis image: redis ports: - containerPort: 6379
-
創(chuàng)建
kubectl create -f xxx.yaml
-
查看
kubectl get pod/po <Pod_name> kubectl get pod/po <Pod_name> -o wide kubectl describe pod/po <Pod_name>
-
刪除
kubectl delete -f pod pod_name.yaml kubectl delete pod --all/[pod_name]
1.3 Pod 的分類
Pod有兩種類型
-
普通Pod
普通Pod一旦被創(chuàng)建,就會(huì)被放入到etcd中存儲(chǔ),隨后會(huì)被Kubernetes Master調(diào)度到某個(gè)具體的Node上并進(jìn)行綁定,隨后該P(yáng)od對(duì)應(yīng)的Node上的kubelet進(jìn)程實(shí)例化成一組相關(guān)的Docker容器并啟動(dòng)起來。在默認(rèn)情況下,當(dāng)Pod里某個(gè)容器停止時(shí),Kubernetes會(huì)自動(dòng)檢測(cè)到這個(gè)問題并且重新啟動(dòng)這個(gè)Pod里某所有容器,如果Pod所在的Node宕機(jī),則會(huì)將這個(gè)Node上的所有Pod重新調(diào)度到其它節(jié)點(diǎn)上。
-
靜態(tài)Pod
靜態(tài)Pod是由kubelet進(jìn)行管理的僅存在于特定Node上的Pod,它們不能通過 API Server進(jìn)行管理,無法與ReplicationController、Deployment或DaemonSet進(jìn)行關(guān)聯(lián),并且kubelet也無法對(duì)它們進(jìn)行健康檢查。
1.4 Pod 生命周期和重啟策略
-
Pod的狀態(tài)
狀態(tài)值 | 說明 |
---|---|
Pending | API Server已經(jīng)創(chuàng)建了該P(yáng)od,但Pod中的一個(gè)或多個(gè)容器的鏡像還沒有創(chuàng)建,包括鏡像下載過程 |
Running | Pod內(nèi)所有容器已創(chuàng)建,且至少一個(gè)容器處于運(yùn)行狀態(tài)、正在啟動(dòng)狀態(tài)或正在重啟狀態(tài) |
Completed | Pod內(nèi)所有容器均成功執(zhí)行退出,且不會(huì)再重啟 |
Failed | Pod內(nèi)所有容器均已退出,但至少一個(gè)容器退出失敗 |
Unknown | 由于某種原因無法獲取Pod狀態(tài),例如網(wǎng)絡(luò)通信不暢 |
-
Pod重啟策略
Pod的重啟策略包括Always、OnFailure和Never,默認(rèn)值是Always
重啟策略 | 說明 |
---|---|
Always | 當(dāng)容器失效時(shí),由kubelet自動(dòng)重啟該容器 |
OnFailure | 當(dāng)容器終止運(yùn)行且退出碼不為0時(shí),由kubelet自動(dòng)重啟該容器 |
Never | 不論容器運(yùn)行狀態(tài)如何,kubelet都不會(huì)重啟該容器 |
-
常見狀態(tài)轉(zhuǎn)換
Pod包含的容器數(shù) | Pod當(dāng)前的狀態(tài) | 發(fā)生事件 | Pod的結(jié)果狀態(tài) | ||
---|---|---|---|---|---|
RestartPolicy=Always | RestartPolicy=OnFailure | RestartPolicy=Never | |||
包含一個(gè)容器 | Running | 容器成功退出 | Running | Succeeded | Succeeded |
包含一個(gè)容器 | Running | 容器成失敗退出 | Running | Running | Failure |
包含兩個(gè)容器 | Running | 1個(gè)容器失敗退出 | Running | Running | Running |
包含兩個(gè)容器 | Running | 容器被OOM殺掉 | Running | Running | Failure |
1.5 Pod資源配置
每個(gè)Pod都可以對(duì)其能使用的服務(wù)器上的計(jì)算資源設(shè)置限額,Kubernetes中可以設(shè)置限額的計(jì)算資源有CPU與Memory兩種,其中CPU的資源單位為CPU數(shù)量,是一個(gè)絕對(duì)值而非相對(duì)值。Memory配額也是一個(gè)絕對(duì)值,它的單位是內(nèi)存字節(jié)數(shù)。
Kubernetes里,一個(gè)計(jì)算資源進(jìn)行配額限定需要設(shè)定以下兩個(gè)參數(shù):
-
Requests 該資源最小申請(qǐng)數(shù)量,系統(tǒng)必須滿足要求
-
Limits 該資源最大允許使用的量,不能突破,當(dāng)容器試圖使用超過這個(gè)量的資源時(shí),可能會(huì)被Kubernetes Kill并重啟
sepc containers: - name: db image: mysql resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m"
上述代碼表明MySQL容器申請(qǐng)最少0.25個(gè)CPU以及64MiB內(nèi)存,在運(yùn)行過程中容器所能使用的資源配額為0.5個(gè)CPU以及128MiB內(nèi)存。
2 Label詳解
Label是Kubernetes系統(tǒng)中另一個(gè)核心概念。一個(gè)Label是一個(gè)key=value的鍵值對(duì),其中key與value由用戶自己指定。Label可以附加到各種資源對(duì)象上,如Node、Pod、Service、RC,一個(gè)資源對(duì)象可以定義任意數(shù)量的Label,同一個(gè)Label也可以被添加到任意數(shù)量的資源對(duì)象上,Label通常在資源對(duì)象定義時(shí)確定,也可以在對(duì)象創(chuàng)建后動(dòng)態(tài)添加或刪除。
Label的最常見的用法是使用metadata.labels字段,來為對(duì)象添加Label,通過spec.selector來引用對(duì)象
apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 3 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80 ------------------------------------- apiVersion: v1 kind: Service metadata: name: nginx spec: type: NodePort ports: - port: 80 nodePort: 3333 selector: app: nginx
Label附加到Kubernetes集群中的各種資源對(duì)象上,目的就是對(duì)這些資源對(duì)象進(jìn)行分組管理,而分組管理的核心就是Label Selector。Label與Label Selector都是不能單獨(dú)定義,必須附加在一些資源對(duì)象的定義文件上,一般附加在RC和Service的資源定義文件中。
3 Replication Controller詳解
Replication Controller(RC)是Kubernetes系統(tǒng)中核心概念之一,當(dāng)我們定義了一個(gè)RC并提交到Kubernetes集群中以后,Master節(jié)點(diǎn)上的Controller Manager組件就得到通知,定期檢查系統(tǒng)中存活的Pod,并確保目標(biāo)Pod實(shí)例的數(shù)量剛好等于RC的預(yù)期值,如果有過多或過少的Pod運(yùn)行,系統(tǒng)就會(huì)停掉或創(chuàng)建一些Pod.此外我們也可以通過修改RC的副本數(shù)量,來實(shí)現(xiàn)Pod的動(dòng)態(tài)縮放功能。
kubectl scale rc nginx --replicas=5
由于Replication Controller與Kubernetes代碼中的模塊Replication Controller同名,所以在Kubernetes v1.2時(shí),它就升級(jí)成了另外一個(gè)新的概念Replica Sets,官方解釋為下一代的RC,它與RC區(qū)別是:Replica Sets支援基于集合的Label selector,而RC只支持基于等式的Label Selector。我們很少單獨(dú)使用Replica Set,它主要被Deployment這個(gè)更高層面的資源對(duì)象所使用,從而形成一整套Pod創(chuàng)建、刪除、更新的編排機(jī)制。最好不要越過RC直接創(chuàng)建Pod,因?yàn)镽eplication Controller會(huì)通過RC管理Pod副本,實(shí)現(xiàn)自動(dòng)創(chuàng)建、補(bǔ)足、替換、刪除Pod副本,這樣就能提高應(yīng)用的容災(zāi)能力,減少由于節(jié)點(diǎn)崩潰等意外狀況造成的損失。即使應(yīng)用程序只有一個(gè)Pod副本,也強(qiáng)烈建議使用RC來定義Pod
4 Replica Set詳解
ReplicaSet 跟 ReplicationController 沒有本質(zhì)的不同,只是名字不一樣,并且 ReplicaSet 支持集合式的
selector(ReplicationController 僅支持等式)。Kubernetes官方強(qiáng)烈建議避免直接使用ReplicaSet,而應(yīng)該通過
Deployment來創(chuàng)建RS和Pod。由于ReplicaSet是ReplicationController的代替物,因此用法基本相同,唯一的區(qū)
別在于ReplicaSet支持集合式的selector。
5 Deployment詳解
Deployment是Kubenetes v1.2引入的新概念,引入的目的是為了更好的解決Pod的編排問題,Deployment內(nèi)部使用了Replica Set來實(shí)現(xiàn)。Deployment的定義與Replica Set的定義很類似,除了API聲明與Kind類型有所區(qū)別:
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend matchExpressions: - {key: tier, operator: In, values: [frontend]} template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: tomcat ports: - containerPort: 8080
6 Horizontal Pod Autoscaler
Horizontal Pod Autoscal(Pod橫向擴(kuò)容 簡(jiǎn)稱HPA)與RC、Deployment一樣,也屬于一種Kubernetes資源對(duì)象。通過追蹤分析RC控制的所有目標(biāo)Pod的負(fù)載變化情況,來確定是否需要針對(duì)性地調(diào)整目標(biāo)Pod的副本數(shù),這是HPA的實(shí)現(xiàn)原理。
Kubernetes對(duì)Pod擴(kuò)容與縮容提供了手動(dòng)和自動(dòng)兩種模式,手動(dòng)模式通過kubectl scale命令對(duì)一個(gè)Deployment/RC進(jìn)行Pod副本數(shù)量的設(shè)置。自動(dòng)模式則需要用戶根據(jù)某個(gè)性能指標(biāo)或者自定義業(yè)務(wù)指標(biāo),并指定Pod副本數(shù)量的范圍,系統(tǒng)將自動(dòng)在這個(gè)范圍內(nèi)根據(jù)性能指標(biāo)的變化進(jìn)行調(diào)整。
-
手動(dòng)擴(kuò)容和縮容
kubectl scale deployment frontend --replicas 1
-
自動(dòng)擴(kuò)容和縮容
HPA控制器基本Master的kube-controller-manager服務(wù)啟動(dòng)參數(shù) --horizontal-pod-autoscaler-sync-period定義的時(shí)長(zhǎng)(默認(rèn)值為30s),周期性地監(jiān)測(cè)Pod的CPU使用率,并在滿足條件時(shí)對(duì)RC或Deployment中的Pod副本數(shù)量進(jìn)行調(diào)整,以符合用戶定義的平均Pod CPU使用率。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 1 template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx resources: requests: cpu: 50m ports: - containerPort: 80 ------------------------------- apiVersion: v1 kind: Service metadata: name: nginx-svc spec: ports: - port: 80 selector: app: nginx ----------------------------------- apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa spec: scaleTargetRef: apiVersion: app/v1beta1 kind: Deployment name: nginx-deployment minReplicas: 1 maxReplicas: 10 targetCPUUtilizationPercentage: 50
7 Volume詳解
Volume是Pod中能夠被多個(gè)容器訪問的共享目錄。Kubernetes的Volume定義在Pod上,它被一個(gè)Pod中的多個(gè)容器掛載到具體的文件目錄下。Volume與Pod的生命周期相同,但與容器的生命周期不相關(guān),當(dāng)容器終止或重啟時(shí),Volume中的數(shù)據(jù)也不會(huì)丟失。要使用volume,pod需要指定volume的類型和內(nèi)容( spec.volumes 字段),和映射到容器的位置( spec.containers.volumeMounts 字段)。 Kubernetes支持多種類型的Volume,包括:emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、nfs、iscsi、flflocker、glusterfs、rbd、cephfs、gitRepo、secret、persistentVolumeClaim、downwardAPI、azureFileVolume、azureDisk、vsphereVolume、Quobyte、PortworxVolume、ScaleIO。
-
emptyDir
EmptyDir類型的volume創(chuàng)建于pod被調(diào)度到某個(gè)宿主機(jī)上的時(shí)候,而同一個(gè)pod內(nèi)的容器都能讀寫EmptyDir中的同一個(gè)文件。一旦這個(gè)pod離開了這個(gè)宿主機(jī),EmptyDir中的數(shù)據(jù)就會(huì)被永久刪除。所以目前EmptyDir類型的volume主要用作臨時(shí)空間,比如Web服務(wù)器寫日志或者tmp文件需要的臨時(shí)目錄。yaml示例如下
apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: docker.io/nazarpc/webserver name: test-container volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}
-
hostPath
HostPath屬性的volume使得對(duì)應(yīng)的容器能夠訪問當(dāng)前宿主機(jī)上的指定目錄。例如,需要運(yùn)行一個(gè)訪問Docker系統(tǒng)目錄的容器,那么就使用/var/lib/docker目錄作為一個(gè)HostDir類型的volume;或者要在一個(gè)容器內(nèi)部運(yùn)行CAdvisor,那么就使用/dev/cgroups目錄作為一個(gè)HostDir類型的volume。一旦這個(gè)pod離開了這個(gè)宿主機(jī),HostDir中的數(shù)據(jù)雖然不會(huì)被永久刪除,但數(shù)據(jù)也不會(huì)隨pod遷移到其他宿主機(jī)上。因此,需要注意的是,由于各個(gè)宿主機(jī)上的文件系統(tǒng)結(jié)構(gòu)和內(nèi)容并不一定完全相同,所以相同pod的HostDir可能會(huì)在不
同的宿主機(jī)上表現(xiàn)出不同的行為。yaml示例如下:
apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: docker.io/nazarpc/webserver name: test-container # 指定在容器中掛接路徑 volumeMounts: - mountPath: /test-pd name: test-volume # 指定所提供的存儲(chǔ)卷 volumes: - name: test-volume # 宿主機(jī)上的目錄 hostPath: # directory location on host path: /data
-
nfs
NFS類型的volume。允許一塊現(xiàn)有的網(wǎng)絡(luò)硬盤在同一個(gè)pod內(nèi)的容器間共享。yaml示例如下:
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: redis spec: selector: matchLabels: app: redis revisionHistoryLimit: 2 template: metadata: labels: app: redis spec: containers: # 應(yīng)用的鏡像 - image: redis name: redis imagePullPolicy: IfNotPresent # 應(yīng)用的內(nèi)部端口 ports: - containerPort: 6379 name: redis6379 env: - name: ALLOW_EMPTY_PASSWORD value: "yes" - name: REDIS_PASSWORD value: "redis" # 持久化掛接位置,在docker中 volumeMounts: - name: redis-persistent-storage mountPath: /data volumes: # 宿主機(jī)上的目錄 - name: redis-persistent-storage nfs: path: /k8s-nfs/redis/data server: 192.168.126.112
8 Namespace詳解
Namespace在很多情況下用于實(shí)現(xiàn)多用戶的資源隔離,通過將集群內(nèi)部的資源對(duì)象分配到不同的Namespace中,形成邏輯上的分組,便于不同的分組在共享使用整個(gè)集群的資源同時(shí)還能被分別管理。Kubernetes集群在啟動(dòng)后,會(huì)創(chuàng)建一個(gè)名為"default"的Namespace,如果不特別指明Namespace,則用戶創(chuàng)建的Pod,RC,Service都將被系統(tǒng) 創(chuàng)建到這個(gè)默認(rèn)的名為default的Namespace中。
-
Namespace創(chuàng)建
apiVersion: v1 kind: Namespace metadata: name: development --------------------- apiVersion: v1 kind: Pod metadata: name: busybox namespace: development spec: containers: - image: busybox command: - sleep - "3600" name: busybox
Namespace查看
kubectl get pods --namespace=development
9 Service 詳解
Service是Kubernetes最核心概念,通過創(chuàng)建Service,可以為一組具有相同功能的容器應(yīng)用提供一個(gè)統(tǒng)一的入口地址,并且將請(qǐng)求負(fù)載分發(fā)到后端的各個(gè)容器應(yīng)用上。
9.1 Service的定義
yaml格式的Service定義文件
apiVersion: v1 kind: Service matadata: name: string namespace: string labels: - name: string annotations: - name: string spec: selector: [] type: string clusterIP: string sessionAffinity: string ports: - name: string protocol: string port: int targetPort: int nodePort: int status: loadBalancer: ingress: ip: string hostname: string
屬性名稱 | 取值類型 | 是否必選 | 取值說明 |
---|---|---|---|
version | string | Required | v1 |
kind | string | Required | Service |
metadata | object | Required | 元數(shù)據(jù) |
metadata.name | string | Required | Service名稱 |
metadata.namespace | string | Required | 命名空間,默認(rèn)為default |
metadata.labels[] | list | 自定義標(biāo)簽屬性列表 | |
metadata.annotation[] | list | 自定義標(biāo)簽屬性列表 | |
spec | object | Required | 詳細(xì)描述 |
spec.selector[] | list | Required | Label Selector配置,將選擇具有指定 Label標(biāo)簽的Pod作為管理范圍 |
spec.type | string | Required | Service的類型,指定Service的訪問方式,默認(rèn)值為ClusterIP。取值范圍如下:ClusterIP: 虛擬服務(wù)的IP,用于k8s集群內(nèi)部的pod訪問,在Node上kube-proxy通過設(shè)置的Iptables規(guī)則進(jìn)行轉(zhuǎn)發(fā)。NodePort:使用宿主機(jī)的端口,使用能夠訪問各Node的外部客戶端通過Node的IP地址和端口就能訪問服務(wù)。LoadBalancer: 使用外接負(fù)載均衡器完成到服務(wù)的負(fù)載分發(fā),需要在spec.status.loadBalancer字段指定外部負(fù)載均衡器的IP地址,并同時(shí)定義nodePort和clusterIP,用于公有云環(huán)境。 |
spec.clusterIP | string | Required | 虛擬服務(wù)的IP地址,當(dāng)type=clusterIP時(shí),如果不指定,則系統(tǒng)進(jìn)行自動(dòng)分配。也可以手工指定。當(dāng) type=LoadBalancer時(shí),則需要指定。 |
spec.sessionAffiffiffinity | string | 是否支持Session,可選值為ClientIP,表示將同一個(gè)源IP地址的客戶端訪問請(qǐng)求都轉(zhuǎn)發(fā)到同一個(gè)后端Pod。默認(rèn)值為空。 | |
spec.ports[] | list | Service需要暴露的端口列表 | |
spec.ports[].name | string | 端口名稱 | |
spec.ports[].protocol | string | 端口協(xié)議,支持TCP和UDP,默認(rèn)值為TCP | |
spec.ports[].port | int | 服務(wù)監(jiān)聽的端口號(hào) | |
spec.ports[].targetPort | int | 需要轉(zhuǎn)發(fā)到后端Pod的端口號(hào) | |
spec.ports[].nodePort | int | 當(dāng)spec.type=NodePort時(shí),指定映射到物理機(jī)的端口號(hào) | |
status | object | 當(dāng)spec.type=LoadBalancer時(shí),設(shè)置外部負(fù)載均衡器的地址,用于公有云環(huán)境 | |
status.loadBalancer | object | 外部負(fù)載均衡器 | |
status.loadBalancer.ingress | object | 外部負(fù)載均衡器 | |
status.loadBalancer.ingress.ip | string | 外部負(fù)載均衡器的IP地址 | |
status.loadBalancer.ingress.hostname | string | 外部負(fù)載均衡器主機(jī)名 |
9.2 Service的基本用法
一般來說,對(duì)外提供服務(wù)的應(yīng)用程序需要通過某種機(jī)制來實(shí)現(xiàn),對(duì)于容器應(yīng)用最簡(jiǎn)便的方式就是通過TCP/IP機(jī)制及監(jiān)聽I(yíng)P和端口號(hào)來實(shí)現(xiàn)。創(chuàng)建一個(gè)基本功能的Service
apiVersion: v1 kind: ReplicationController metadata: name: mywebapp spec: replicas: 2 template: metadata: name: mywebapp labels: app: mywebapp spec: containers: - name: mywebapp image: tomcat ports: - containerPort: 8080
我們可以通過kubectl get pods -l app=mywebapp -o yaml | grep podIP來獲取Pod的IP地址和端口號(hào)來訪問Tomcat服務(wù),但是直接通過Pod的IP地址和端口訪問應(yīng)用服務(wù)是不可靠的,因?yàn)楫?dāng)Pod所在的Node發(fā)生故障時(shí),Pod將被kubernetes重新調(diào)度到另一臺(tái)Node,Pod的地址會(huì)發(fā)生改變。我們可以通過配置文件來定義Service,再通過kubectl create來創(chuàng)建,這樣可以通過Service地址來訪問后端Pod.
apiVersion: v1 kind: Service metadata: name: mywebAppService spec: ports: - port: 8081 targetPort: 8080 selector: app: mywebapp
9.2.1 多端口Service
有時(shí)一個(gè)容器應(yīng)用也可能需要提供多個(gè)端口的服務(wù),那么在Service的定義中也可以相應(yīng)地設(shè)置為將多個(gè)端口對(duì)應(yīng)到多個(gè)應(yīng)用服務(wù)。文章來源:http://www.zghlxwxcb.cn/news/detail-744829.html
apiVersion: v1 kind: Service metadata: name: mywebAppService spec: ports: - port: 8080 targetPort: 8080 name: web - port: 8005 targetPort: 8005 name: management selector: app: mywebapp
9.2.2 外部服務(wù)Service
在某些特殊環(huán)境中,應(yīng)用系統(tǒng)需要將一個(gè)外部數(shù)據(jù)庫作為后端服務(wù)進(jìn)行連接,或?qū)⒘硪粋€(gè)集群或Namespace中的服務(wù)作為服務(wù)的后端,這時(shí)可以通過創(chuàng)建一個(gè)無Label Selector的Service來實(shí)現(xiàn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-744829.html
apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - protocol: TCP port: 80 targetPort: 80 -------------------------- apiVersion: v1 kind: Endpoints metadata: name: my-service subsets: - addresses: - IP: 10.254.74.3 ports: - port: 8080
到了這里,關(guān)于容器化進(jìn)階Kubernetes(K8S)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!