K8s基礎原理
k8s中文社區:https://www.kubernetes.org.cn/
簡介
Kubernetes與較早的集群管理系統Mesos和YARN相比,對容器尤其是 Docker的支持更加原生,同時提供了更強大的機制實現資源調度,自動 管理容器生命周期,負載均衡,高可用等底層功能,使開發者可以專注於開發應用。
Kubernetes是一個開源的,用於管理雲平台中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效(powerful),Kubernetes提供了應用部署,規划,更新,維護的一種機制。
K8s特性
Kubernetes是為生產環境而設計的容器調度管理系統,對於負載均衡、 服務發現、高可用、滾動升級、自動伸縮等容器雲平台的功能要求有原生支持
一個K8s集群是由分布式存儲(etcd)、服務節點(Minion, etcd現在稱為Node)和控制節點(Master)構成的。所有的集群狀態都保存在etcd中,Master節點上則運行集群的管理控制模塊。Node節點是真正運行應用容器的主機節點,在每個Minion節點上都會運行一個Kubelet代理,控制該節點上的容器、鏡像和存儲卷等。
K8s架構圖,介紹
Master(管理節點)
- API Server:供Kubernetes API接口,主要處理 Rest操作以及更新Etcd中的對象。 所有資源增刪改查的唯一入口。
- Scheduler:綁定Pod到Node上,資源調度。
- Controller Manager: 所有其他群集級別的功能,目前由控制器Manager執行。資源對象的 自動化控制中心。
- Etcd:所有持久化的狀態信息存儲在Etcd中。
Node(計算節點)
- Kubelet:管理Pods以及容器、鏡像、Volume等,實現對集群 對節點的管理
- Kube-proxy:提供網絡代理以及負載均衡,實現與Service通訊。
- Docker Engine:負責節點的容器的管理工作。
API SERVER(授權)
- 只有API Server與存儲通信,其他模塊通過 API Server訪問集群狀態。
- 一個工作節點的問題不影響集群體。
- 在K8s集群中,所有的配置管理操作都聲明 式而非命令式的。
- 各個模塊在內存中緩存自己的相關狀態以 提高系統性能。
Scheduler(資源調度)
- 負責集群的資源調度,根據特定的調度算法將pod調度到指定的minion上。
- 這部分工作分出來變成一個組件,意味着可以很方便地替換成其他的調度器。
- Scheduler調度器輸入是待調度pod和可用的工作節點列表,輸出則是應用調度 算法從列表中選擇一個最優的用於綁定待調度的pod節點。
Controller Manager(控制管理中心)
- Controller Manager作為集群內部的管理控制中心,負責集群內的Node、Pod副本、服務端點、命名空間、服務賬號、資源定額等的管理並執行自動化修復流程,確保集群處於預期的工作狀態
- 在Kubernetes集群中,每個Controller就是一個操作系統,它通過API Server監控系統的共享狀態,並嘗試着將系統狀態從“現有狀態”修正到“期望狀態”
POD(資源池)
- Pod是K8s集群中所有業務類型的基礎
- Pod是在K8s集群中運行部署應用或服務的最小單元,它是可以支持多容器的。
- Pod的設計理念是支持多個容器在一個Pod中共享網絡地址和文件系統。
- POD控制器Deployment、Job、DaemonSet和 PetSet
LABEL(標簽)
- Label是一個 key=value的鍵值對,由用戶指定,可以附加到 K8S資源之上。
- 給某個資源定義一個標簽,隨后可以通過label進行查詢和篩選 ,類似SQL的where語句。
- Label可以給對象創建多組標簽
Replication Controller,RC
- RC是K8s集群中最早的保證Pod高可用的API對象。通過監控運行中的Pod來保證集群中運行指定數目的Pod副本。
- 指定的數目可以是多個也可以是1個;少於指定數目,RC就會啟動運行新的Pod副本;多於指定數目,RC就會殺死多余的Pod副本。
- 即使在指定數目為1的情況下,通過RC運行Pod也比直接運行Pod更明智,因為RC也可以發揮它高可用的能力,保證永遠有1個Pod在運行。
PC總結
- RC里包括完整的POD定義模板
- RC通過Label Selector(標簽選擇器)機制實現對POD副本的自動控制。
- 通過改變RC里的POD副本以實現POD的擴容和縮容
- 通過改變RC里POD模塊中的鏡像版本,可以實現POD的滾動升級。
K8s組件
K8s安裝配置
K8s安裝方法
yum安裝 1.5.2
二進制安裝
kubeadm安裝(官方) 需要梯子,全部容器化
minkube安裝
編譯安裝
自動化安裝
K8s資源
官網 kubernetes.io
中文社區 https://www.kubernetes.org.cn/
Github https://github.com/kubernetes/kubernetes
命令行參考 https://kubernetes.io/docs/reference/generated/kub ectl/kubectl-commands#
K8s的安裝環境要求
1、linux 內核3.10以上
2、64位系統
3、內存4G
4、安裝epel
5、安裝docker
6、開啟yum cache保存安裝RPM包
K8s中有三種類型的ip
物理ip(宿主機ip)
集群ip(cluster ip):10.254.0.0/16
pod(容器的ip):172.16.0.0/16
K8s安裝與使用
安裝
環境:三台機器,兩個node(計算節點),一個主節點(master)
yum源需要:repo:CentOS-Base.repo docker1.12
主節點(master)
主機名:K8s-master ip:10.0.0.11 系統:centos7.2
yum install etcd -y yum install docker -y yum install kubernetes -y yum install flannel -y
計算節點(node)
K8s-node-1 10.0.0.12 centos7.2
K8s-node-2 10.0.0.13 centos7.2
yum install docker -y yum install kubernetes -y yum install flannel -y
在master節點上
修改配置
修改etcd配置文件
[root@k8s-master ~]# vim /etc/etcd/etcd.conf ETCD_NAME="default" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.11:2379"
啟動
systemctl enable etcd.service
systemctl start etcd.service
檢查
[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
修改/etc/kubernetes/apiserver
vim /etc/kubernetes/apiserver 8 KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0" 11 KUBE_API_PORT="--port=8080" 17 KUBE_ETCD_SERVERS="--etcd-servers=http://10.0.0.11:2379" 23 KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
修改/etc/kubernetes/config
vim /etc/kubernetes/config 22 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
查看是否啟動成功
systemctl status kube-apiserver.service kube-controller-manager.service kube-scheduler.service
在node節點
vim /etc/kubernetes/config KUBE_MASTER="--master=http://10.0.0.11:8080"
node-1
vim /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"
node-2
vim /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"
啟動檢查
systemctl enable kubelet.service systemctl start kubelet.service systemctl enable kube-proxy.service systemctl start kube-proxy.service
檢查:
[root@k8s-master ~]# kubectl get nodes NAME STATUS AGE 10.0.0.12 Ready 3m 10.0.0.13 Ready 3m
配置flannel網絡
修改配置文件
master、node上均編輯/etc/sysconfig/flanneld
vim /etc/sysconfig/flanneld FLANNEL_ETCD_ENDPOINTS="http://10.0.0.11:2379"
配置flannel的網絡范圍
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
K8s常見命令操作
命令:kubectl create -f hello.yaml
文件內容:
[root@k8s-master ~]# vim hello.yaml apiVersion: v1 kind: Pod metadata: name: hello-world spec: restartPolicy: Never containers: - name: hello image: "docker.io/busybox:latest" command: ["/bin/echo","hello”,”world"]
實操:
[root@k8s-master ~]# kubectl create -f hello.yaml pod "hello-world" created kubectl get pods 查看默認name信息 kubectl describe pods hello-world 查看hello-world的詳細信息 kubectl delete pods hello-world 刪除名叫hello-world kubectl replace -f nginx-rc.yaml 對已有資源進行更新、替換 kubectl edit rc nginx 對現有資源直接進行修改,立即生效 kubectl logs nginx-gt1jd 查看訪問日志
存在的坑
因為沒有證書,拉取圖像失敗。

[root@k8s-master ~]# kubectl describe pods hello-world Name: hello-world Namespace: default Node: 10.0.0.13/10.0.0.13 Start Time: Fri, 02 Feb 2018 19:28:31 +0800 Labels: <none> Status: Pending IP: Controllers: <none> Containers: hello: Container ID: Image: docker.io/busybox:latest Image ID: Port: Command: /bin/echo hello”,”world State: Waiting Reason: ContainerCreating Ready: False Restart Count: 0 Volume Mounts: <none> Environment Variables: <none> Conditions: Type Status Initialized True Ready False PodScheduled True No volumes. QoS Class: BestEffort Tolerations: <none> Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 4m 4m 1 {default-scheduler } Normal Scheduled Successfully assigned hello-world to 10.0.0.13 4m 1m 5 {kubelet 10.0.0.13} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "POD" with ErrImagePull: "image pull failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest, this may be because there are no credentials on this request. details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)" 3m 5s 16 {kubelet 10.0.0.13} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "POD" with ImagePullBackOff: "Back-off pulling image \"registry.access.redhat.com/rhel7/pod-infrastructure:latest\""
解決:yum install python-rhsm* -y
創建:
[root@k8s-master ~]# kubectl create -f nginx.yaml pod "hello-nginx" created
檢查是否成功
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE hello-nginx 1/1 Running 0 2h 172.16.42.2 10.0.0.13
RC:保證高可用
- RC是K8s集群中最早的保證Pod高可用的API對象。通過監控運行中的Pod來保證集群中運行指定數目的Pod副本。
- 指定的數目可以是多個也可以是1個;少於指定數目,RC就會啟動運行新的Pod副本;多於指定數目,RC就會殺死多余的Pod副本。
- 即使在指定數目為1的情況下,通過RC運行Pod也比直接運行Pod更明智,因為RC也可以發揮它高可用的能力,保證永遠有1個Pod在運行。
始終保持一個在活着
rc版yaml編寫:
[root@k8s-master ~]# cat nginx-rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 1 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
啟動rc版容器
[root@k8s-master ~]# kubectl create -f nginx-rc.yaml replicationcontroller "nginx" created
檢查:
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-gt1jd 1/1 Running 0 2m 172.16.79.2 10.0.0.12
這樣的話就算刪除了這個容器RC也會立馬在起一個
版本升級
[root@k8s-master ~]# cat web-rc2.yaml apiVersion: v1 kind: ReplicationController metadata: name: myweb-2 spec: replicas: 2 selector: app: myweb-2 template: metadata: labels: app: myweb-2 spec: containers: - name: myweb-2 image: kubeguide/tomcat-app:v2 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
升級操作:
[root@k8s-master ~]# kubectl rolling-update myweb -f web-rc2.yaml Created myweb-2 Scaling up myweb-2 from 0 to 2, scaling down myweb from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling myweb-2 up to 1 Scaling myweb down to 1 Scaling myweb-2 up to 2 Scaling myweb down to 0 Update succeeded. Deleting myweb replicationcontroller "myweb" rolling updated to "myweb-2"
升級過程
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myweb-2-mmlcm 1/1 Running 0 32s 172.16.42.3 10.0.0.13 myweb-71438 1/1 Running 0 2m 172.16.42.2 10.0.0.13 myweb-cx9j2 1/1 Running 0 2m 172.16.79.3 10.0.0.12 nginx-gt1jd 1/1 Running 0 1h 172.16.79.2 10.0.0.12 [root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myweb-2-0kmzf 1/1 Running 0 7s 172.16.79.4 10.0.0.12 myweb-2-mmlcm 1/1 Running 0 1m 172.16.42.3 10.0.0.13 myweb-cx9j2 1/1 Running 0 2m 172.16.79.3 10.0.0.12 nginx-gt1jd 1/1 Running 0 1h 172.16.79.2 10.0.0.12
回滾
[root@k8s-master ~]# cat web-rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: myweb spec: replicas: 2 selector: app: myweb template: metadata: labels: app: myweb spec: containers: - name: myweb image: kubeguide/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
操作:
[root@k8s-master ~]# kubectl rolling-update myweb-2 -f web-rc.yaml Created myweb Scaling up myweb from 0 to 2, scaling down myweb-2 from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling myweb up to 1 Scaling myweb-2 down to 1 Scaling myweb up to 2 Scaling myweb-2 down to 0 Update succeeded. Deleting myweb-2 replicationcontroller "myweb-2" rolling updated to "myweb"
檢查
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myweb-mbndc 1/1 Running 0 1m 172.16.79.3 10.0.0.12 myweb-qh38r 1/1 Running 0 2m 172.16.42.2 10.0.0.13 nginx-gt1jd 1/1 Running 0 1h 172.16.79.2 10.0.0.12
svc設置
[root@k8s-master ~]# cat web-svc.yaml apiVersion: v1 kind: Service metadata: name: myweb spec: type: NodePort ports: - port: 8080 nodePort: 30001 selector: app: myweb
[root@k8s-master ~]# kubectl create -f web-svc.yaml
[root@k8s-master ~]# kubectl get svc NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.254.0.1 <none> 443/TCP 6h myweb 10.254.91.34 <nodes> 8080:30001/TCP 1m
然后取node節點檢查30001端口是否啟動
然后瀏覽器web訪問node節點的ip:30001進行測試
web界面管理
[root@k8s-master ~]# cat 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
操作:
[root@k8s-master ~]# cat dashboard-svc.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
啟動:
kubectl create -f dashboard.yaml
kubectl create -f dashboard-svc.yaml
然后訪問:http://10.0.0.11:8080/ui/