k8s技術預研1--通過一個簡單例項認識k8s基礎概念知識
一、Kubernetes基礎知識
1、在Kubernete中,Service是分散式叢集架構的核心,一個Service物件擁有如下關鍵特徵
- 擁有一個唯一指定的名字。
- 擁有一個虛擬IP和埠號。
- 能夠提供某種遠端服務能力。
- 被對映到了提供這種服務能力的一組容器應用上。
- Service是從應用視角觀察得到的。
2、什麼是Pod物件
- 把為Service提供服務的一組程序放入容器中進行隔離,即誕生了Pod物件,每個服務程序都將是Pod中執行的一個容器。
- Kubernete給Pod打上一個標籤Label,然後給Service定義了一個標籤選擇器Label Selector,這樣二者就可以建立關聯關係了。
- Pod是從系統視角觀察得到的。
3、什麼是Node
- Pod執行在一個稱之為Node的環境中
- Node可以是物理機、虛機或雲主機
- 通常在一個Node上執行幾百個Pod。
4、什麼是Pause容器和業務容器
- 在每個Pod中又運行了一個稱之為Pause的特殊容器,而其它容器則屬於業務容器。
- 業務容器共享Pause容器的網路棧和Volume掛載卷,因此它們之間的通訊和資料交換更為高效。
- 在設計時我們可以充分利用以上特性將一組密切相關的服務程序放入同一個Pod中。
- 需要注意的是,並不是每個Pod和它裡面執行的容器都能“對映”到一個Service上。只有那些向外界提供服務的一組Pod才會被這樣配置。
5、Kubernete的叢集管理
- Kubernete將叢集中的機器劃分為一個Master節點和一群工作節點(Node);
- 在Master節點上執行著叢集管理相關的一組程序kube-apiserver、kube-controller-manager和kube-scheduler 。這些程序實現了整個叢集的資源管理、Pod排程、彈性伸縮、安全控制、系統監控和糾錯等管理功能,且都是自動完成的。
- Node作為工作節點,執行真正的應用程式。Node上執行著Kubernetes的kublete、kube-proxy服務程序。在Node上Kubernetes管理的最小執行單元是Pod。這些服務程序負責Pod的建立、啟動、監控、重啟、銷燬以及負載均衡服務。
6、RC(Replication Controller),為Kubernetes提供了自動擴容功能的支援。在一個RC定義檔案中會包括以下3個資訊:
- 目標Pod的定義
- 目標Pod需要執行的副本數量
- 要監控的目標Pod的標籤
RC執行機制:
- 在建立好RC後,Kubernetes會通過RC中定義的Label挑選出對應的Pod例項並實時監控其狀態和數量。
- 如果例項數量少於定義的副本數量,則會根據RC中定義的Pod模板來建立一個新的Pod,然後將此Pod排程到合適的Node上啟動執行,直到Pod例項的數量達到預定目標。
- 使用RC後,服務的擴容就成了簡單的修改RC中副本數量的操作了。
二、環境準備
以下實驗均是使用CentOS7.4 Minimual版本系統完成。
1、關閉系統防火牆
systemctl disable firewalld
systemctl stop firewalld
2、安裝etcd和Kubernetes軟體
yum -y install etcd kubernetes
3、按順序啟動所有的服務
systemctl start etcd
systemctl start docker
systemctl start kube-apiserver
systemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl start kubelet
systemctl start kube-proxy
一個單機版的kubernete就安裝完成了。
4、建立和啟動一個MySQL服務
(1)定義一個RC檔案:mysql-rc.yaml
apiVersion: v1
kind: ReplicationController #型別為副本控制器RC
metadata:
name: mysql #RC的名稱,全域性唯一
spec:
replicas: 1 #POD副本期待數量
selector:
app: mysql #符合目標的Pod擁有此標籤
template: #根據此模板建立Pod的副本
metadata:
labels:
app: mysql #Pod副本擁有的標籤,對應RC的Selector
spec:
containers: #Pod內容器的定義部分
- name: mysql #容器的名稱
image: mysql.io/mysql:latest #容器對應的Docker Image
ports:
- containerPort: 3306 #容器應用監聽的埠號
env: #注入容器內的環境變數
- name: MYSQL_ROOT_PASSWORD
value: "123456"
在Master節點執行建立命令:
# kubectl create -f mysql-rc.yaml
replicationcontroller "mysql" created
檢視剛剛建立的RC:
# kubectl get rc
NAME DESIRED CURRENT READY AGE
mysql 1 0 0 26s
檢視Pod的建立情況:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
注:在建立Pod例項的過程視宿主機效能差異,有時需要待一會。如果立即檢視,會像上面顯示的樣子,還不會立即有結果。
(2)故障排除1
在等了一會兒後發現仍然檢視不到正確的建立Pod的結果,於是檢視相關日誌tail -200 /var/log/messages,看到下面報錯資訊。
Feb 18 02:09:53 gqtest kube-controller-manager: I0218 02:09:53.543524 1230 event.go:217] Event(api.ObjectReference{Kind:"ReplicationController", Namespace:"default", Name:"mysql", UID:"8ace1e3a-140d-11e8-961e-0800275f8277", APIVersion:"v1", ResourceVersion:"15425", FieldPath:""}): type: 'Warning' reason: 'FailedCreate' Error creating: No API token found for service account "default", retry after the token is automatically created and added to the service account
屬於K8S服務間介面呼叫授權問題,可以通過以下方法解決:
vi /etc/kubernetes/apiserver
# default admission control policies
# KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota"
再檢視Pod建立結果:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 0/1 ContainerCreating 0 27s
(3)故障排除2
又是等待了好一會兒,一直停滯在ContainerCreating的狀態,繼續檢視日誌或者使用以下方法檢視Pod建立資訊:
# kubectl describe pod mysql
Name: mysql-mn49n
Namespace: default
Node: 127.0.0.1/127.0.0.1
Start Time: Sun, 18 Feb 2018 02:17:26 +0800
Labels: app=mysql
Status: Pending
IP:
Controllers: ReplicationController/mysql
Containers:
mysql:
Container ID:
Image: docker.io/mysql:latest
Image ID:
Port: 3306/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Volume Mounts: <none>
Environment Variables:
MYSQL_ROOT_PASSWORD: 123456
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 mysql-mn49n to 127.0.0.1
4m 1m 5 {kubelet 127.0.0.1} 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)"
4m 3s 16 {kubelet 127.0.0.1} 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\""
檢視這個檔案:
# ls -l /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt
lrwxrwxrwx. 1 root root 27 Feb 17 21:39 /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt -> /etc/rhsm/ca/redhat-uep.pem
可以繼續看到上面缺少的是一個符號連結指向的物理檔案:/etc/rhsm/ca/redhat-uep.pem
找了一些簡單的資料,顯示rhsm是redhat用於管理服務註冊管理的一個軟體包,雖然我們使用的開源CentOS系統,用不到這個檔案,但顯然K8S對此有依賴。
因此,也安裝一個該工具包。
# yum search rhsm
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.shu.edu.cn
* epel: mirrors.ustc.edu.cn
* extras: mirror.bit.edu.cn
* updates: mirror.bit.edu.cn
======================================================================== N/S matched: rhsm ========================================================================
python-rhsm.x86_64 : A Python library to communicate with a Red Hat Unified Entitlement Platform
python-rhsm-certificates.x86_64 : Certificates required to communicate with a Red Hat Unified Entitlement Platform
# yum -y install rhsm
再次檢視Pod建立結果,看到建立了一個名為mysql-mn49n的容器,顯示狀態已經變為了Running:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 1/1 Running 0 13m
檢視產生了哪些新的docker容器:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5d627846fe docker.io/mysql:latest "docker-entrypoint.sh" About a minute ago Up About a minute k8s_mysql.162321c7_mysql-mn49n_default_cee70dc4-140e-11e8-9692-0800275f8277_a8673105
1ab87e554d8a registry.access.redhat.com/rhel7/pod-infrastructure:latest "/usr/bin/pod" About a minute ago Up About a minute k8s_POD.1d520ba5_mysql-mn49n_default_cee70dc4-140e-11e8-9692-0800275f8277_896ea006
注:共新建了兩個docker容器,其中後面那個顯然是K8S用於Pod內部網路和其他基礎功能管理使用的一個容器。
(4)為上面的建立服務建立一個與之關聯的K8s Service的定義檔案
apiVersion: v1
kind: Service #型別為k8s Service
metadata:
name: mysql #該Service的全域性唯一名稱
spec:
ports:
- port: 3306 #Service提供服務的埠號
selector: #Service對應的Pod擁有這裡定義的標籤
app: mysql
執行建立命令:
[[email protected] ~]# kubectl create -f mysql-svc.yaml
service "mysql" created
[[email protected] ~]# kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 4h
mysql 10.254.20.191 <none> 3306/TCP 11s
[[email protected] ~]#
可以看到,mysql服務已經被分配了一個10.154.20.191的cluster ip地址。
這是一個虛地址,k8s叢集中其他Pod就可以通過Service的Cluster IP+埠號3306來連線這個mysql服務了。
5、啟動Tomcat應用
再建立一個tomcat應用,來訪問上一步建立的mysql服務,提供一個簡單的web功能。
(1)首先建立tomcat服務使用的RC檔案
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2 #在這裡選擇配置成了2個副本
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: docker.io/kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: 'mysql'
- name: MYSQL_SERVICE_PORT
value: '3306'
執行建立命令:
# kubectl create -f myweb-rc.yaml
檢視結果:
[[email protected] ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 1/1 Running 0 41m
myweb-k6fp0 0/1 ContainerCreating 0 2m
myweb-m9nv9 0/1 ContainerCreating 0 2m
[[email protected] ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-mn49n 1/1 Running 0 42m
myweb-k6fp0 1/1 Running 0 3m
myweb-m9nv9 1/1 Running 0 3m
(2)繼續建立對應的Service
需要特別注意的是,在該Service檔案中用到了type=NodePort和nodePort=30001這兩個重要屬性。
表明此Service開啟了NodePort方式的外網訪問模式。
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
[[email protected] ~]# kubectl create -f myweb-svc.yaml
service "myweb" created
[[email protected] ~]# kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 4h
mysql 10.254.20.191 <none> 3306/TCP 19m
myweb 10.254.89.4 <nodes> 8080:30001/TCP 1m
(3)測試下tomcat和mysql兩個服務是否可以正確得互相連通並提供web服務
(4)檢視一下此時系統中有哪些docker容器、哪些Pods
參考:《Kubernetes權威指南——從Docker到Kubernetes實踐全接觸》第1章。
相關推薦
k8s技術預研1--通過一個簡單例項認識k8s基礎概念知識
一、Kubernetes基礎知識 1、在Kubernete中,Service是分散式叢集架構的核心,一個Service物件擁有如下關鍵特徵 擁有一個唯一指定的名字。 擁有一個虛擬IP和埠號。 能夠提供某種遠端服務能力。 被對映到了提供這種服務能力的一組容器應用上。
k8s技術預研12--kubernetes的常見開源網路元件
k8s的網路模型假定了所有Pod都在一個可以直接連通的扁平的網路空間中。這是因為k8s出自Google,而在GCE裡面是提供了網路模型作為基礎設施的,所以k8s就假定這個網路已經存在。而在大傢俬有的平臺設施裡搭建k8s叢集,就不能假定這種網路已經存在了。我們需要自己實現這個網路,將不同節點上的Docker容器
k8s技術預研8--深入掌握Kubernetes Service
本文內容已經基於k8s v1.8.8進行了驗證測試。k8s的Service定義了一個服務的訪問入口地址,前端的應用通過這個入口地址訪問其背後的一組由Pod副本組成的叢集例項,來自外部的訪問請求被負載均衡到後端的各個容器應用上。Service與其後端Pod副本叢集之間則是通過Label Selector來實現對
k8s技術預研13--kubernetes共享儲存原理與動態儲存供應用使用示例
1、共享儲存機制概述Kubernetes對於有狀態的容器應用或者對於資料需要持久化的應用,不僅需要將容器內的目錄掛載到宿主機的目錄或者emptyDir臨時儲存卷,而且需要更加可靠的儲存來儲存應用產生的重要資料,以便容器應用在重建之後,仍然可以使用之前的資料。不過,儲存資源和計
作業1開發一個簡單的python計算器
加減 pytho 公式 實的 group 運算 作業 得出 必須 開發一個簡單的python計算器 實現加減乘除及拓號優先級解析 用戶輸入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14
Ngnix技術研究系列1-通過應用場景看Nginx的反向代理
emca pid 開頭 plain 性能 xxx md5 重新 行數 隨著我們業務規模的不斷增長,整個系統規模由兩年前的幾十臺服務器,井噴到現在2個數據中心,接近400臺服務器,上百個WebApi站點,上百個域名。 這麽多的WebApi站點這麽多的域名,管理和維護成本很高
初學html,任務1:一個簡單html頁面,要求:內容頁面裝一篇文章 用html來分段
enter pos 工程師 分享圖片 visit 技術 運行 並且 center 這是主要內容部分,用html實現版塊分布。 接下來是樣式部分。 讓頁面所有元素的padding和margin都設置為0 ; 否則加入一張大的覆蓋的背景圖片後,會由於瀏覽器的緣故,圖片周邊有
web前端課程技術內容之如何做一個簡單的手機端頁面的翻頁
【如何做一個簡單的手機端頁面的翻頁】 第一步:建立移動端頁面內 HTML + CSS 【注】可用彈性佈局 但需要注意的是 外層盒子的定位 第二步: 思考問題 要實現怎樣的效果? 手指滑動時觸發事件【左右】兩個方向 2.點選footer部分的下標實現切換效果 3.點選footer部分的下標實
JAVA WEB快速入門之通過一個簡單的Spring專案瞭解Spring的核心(AOP、IOC)
接上篇《JAVA WEB快速入門之從編寫一個JSP WEB網站了解JSP WEB網站的基本結構、除錯、部署》,通過一個簡單的JSP WEB網站了解了JAVA WEB相關的知識,比如:Servlet、Fitler、Listner等,這為後面搭建基於SSM的框架奠定了基礎知識,當然光了解JSP相關的知識還不行,我
MyBatis學習筆記(1)---一個簡單MyBatis示例
利用JDBC仍舊存在的幾個侷限性: 在應用程式中存在的大量程式碼冗餘。 業務程式碼與資料庫訪問程式碼混雜在一起。 SQL語句與Java程式碼混雜在一起。 JDBC丟擲費力難懂的checked異常,需要程式設計師花費精力小心處理。 需要程式設計師自行解決ORM
$python爬蟲系列(1)——一個簡單的爬蟲實例
name 響應 -s 鏈接 實例 blog itl 匹配 列表 本文主要實現一個簡單的爬蟲,目的是從一個百度貼吧頁面下載圖片。 1. 概述 本文主要實現一個簡單的爬蟲,目的是從一個百度貼吧頁面下載圖片。下載圖片的步驟如下: 獲取網頁html文本內容; 分析html中圖
$python爬蟲系列(1)——一個簡單的爬蟲例項
本文主要實現一個簡單的爬蟲,目的是從一個百度貼吧頁面下載圖片。 1. 概述 本文主要實現一個簡單的爬蟲,目的是從一個百度貼吧頁面下載圖片。下載圖片的步驟如下: 獲取網頁html文字內容; 分析html中圖片的html標籤特徵,用正則解析出所有的
通過一個簡單的音樂播放器探討 Android Aidl 的實現原理
眾所周知,音樂播放器的播放不應該在前臺程序,而是要在另外一個程序的 Service 中進行,這樣才能實現後臺播放功能,同時不影響 UI 程序且不共用記憶體資源從而減少雙方被 kill 的可能性。 由於不同程序間是無法直接通訊的,因此在這種情況我們會使用 AID
Spring Boot學習筆記1——搭建一個簡單的Spring Boot專案
1.建立一個Maven專案匯入相應的依賴 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocatio
有章法的學習c++(1)編寫一個簡單的c++程式
(前面進行了一天工作的小小總結,可以直接跳到紅字部分看主要內容) 今天早上提前一些時間到了辦公室,看了會c++,時間有限所以做的不多。 然後開始正式的上班工作。現在在做的工作是更換ide和專案管理工具。本來使用的ide是eclipse,使用的專案管理工具是maven,後應要
手機螢幕適配技術預研
前言 隨著手機螢幕的不斷的變化,同時也遇到一些使用者手機螢幕還是處於240*320這種螢幕的大小,當然也存著在一些不規則的螢幕解析度心寸大小。對於很多的UI來說,不同的手機螢幕很多時候得出多套的圖才能保證手機客戶端在不同的螢幕上實現匹配。針對手機客戶端在不同螢幕下的實現進
用flask開發個人部落格(1)—— 一個簡單的flask程式
1、建立flask程式例項 from flask import Flask app=Flask(__name__) Flask接受一個字串作為引數,這個引數決定程式的根目錄,以便於能找到相對於程式根目錄的資原始檔的位置,通常這種情況下都使用 __nam
sharepoint 2010 自定義欄位開發(1) 建立一個簡單的列表自定義欄位
在sharepoint 2010 中,最常用的就是對自定義列表或者文件庫的使用,建立一個自定義列表或者文件庫,新增一些需要的欄位,sharepoint 2010 自帶了很多不同型別的控制元件供欄位使用,如下圖 很多特殊情況下,這些型別控制元件,不一定能滿足我們的需求,所以
南京華為技術預研面試經歷
按照約定,下班就直奔新街口的長髮銀座,不過想找到能上到7樓的電梯還真是有點困難,繞著轉了一圈,很失敗的先上了B座電梯,發現7樓的按鈕按不了,最後才登上了A座電梯,到達了7樓。一出電梯門,偌大的幾個華為南京研究所幾個字,做了一個前臺mm,很新潮,不過臉上的粉抹得似乎太多了,頓時
Go語言之從0到1實現一個簡單的Redis連線池
Go語言之從0到1實現一個簡單的Redis連線池 前言 最近學習了一些Go語言開發相關內容,但是苦於手頭沒有可以練手的專案,學的時候理解不清楚,學過容易忘。 結合之前組內分享時學到的Redis相關知識,以及Redis Protocol文件,就想著自己造個輪子練練手。 這次我把目標放在了Redis client