Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
天給大家?guī)淼氖巧炜s的輸入框的動畫。大家可以看到,點擊之后包括用戶名往上推,輸入框進行升高。其實這個在很多地方也可以用到,在實際項目中。長話短說,看代碼區(qū)域。
我用開發(fā)工具是hpdx開發(fā)uni app的,大家應(yīng)該很熟悉了。vivo式組容器,可以看到里面包含了第二層vivo式組容器、important輸入框組件、文本組件,還有一條線。我用i來定義,就是這條線。這里面的有基礎(chǔ)同學(xué)可以知道,如果是真的時候是一個樣式,如果是假的時候另一個樣式互相切換的。
怎么在哪控制?通過input的定義了一下,在這使用type-c進行真假的切換。包括這兩個線條為什么會延伸高度?因為這地方定義了四十四px和二px,遇到真的時候是一種高度,遇到假時候是一種高度,這是動態(tài)的樣式,大家要記住。
css部分其實是很少的,就是靜態(tài)的、固定的。可以看到第一層優(yōu)勢圖容器進行全局的定義,第二層就能相對定位和寬度的設(shè)置。輸入框的樣式進行相對定位,那邊去透明,文字顏色、字體大小等等。這地方也可以輸入文字,對文本也進行了央視的開發(fā)。大家可以看我這注釋,就是很詳細的。
進行線條的定義,就這三部分,大家可以看到,大概思路就這么個思路,大家可以動手去寫一下。
喜歡的同學(xué)可以點贊收藏,想要源代碼的可以找我嘮嗑進行獲取或者點擊下方都行,還是建議大家去動手去寫一下。今天推薦的伸縮版的輸入框的樣式就今天就講到這里,謝謝大家。
<html>
<head>
<title>伸縮的菜單</title>
<style>
<!--
body{
background-color:#ffdee0;
}
#navigation {
width:200px;
font-family:Arial;
}
#navigation > ul {
list-style-type:none; /* 不顯示項目符號 */
margin:0px;
padding:0px;
}
#navigation > ul > li {
border-bottom:1px solid #ED9F9F; /* 添加下劃線 */
}
#navigation > ul > li > a{
display:block; /* 區(qū)塊顯示 */
padding:5px 5px 5px 0.5em;
text-decoration:none;
border-left:12px solid #711515; /* 左邊的粗紅邊 */
border-right:1px solid #711515; /* 右側(cè)陰影 */
}
#navigation > ul > li > a:link, #navigation > ul > li > a:visited{
background-color:#c11136;
color:#FFFFFF;
}
#navigation > ul > li > a:hover{ /* 鼠標(biāo)經(jīng)過時 */
background-color:#990020; /* 改變背景色 */
color:#ffff00; /* 改變文字顏色 */
}
/* 子菜單的CSS樣式 */
#navigation ul li ul{
list-style-type:none;
margin:0px;
padding:0px 0px 0px 0px;
}
#navigation ul li ul li{
border-top:1px solid #ED9F9F;
}
#navigation ul li ul li a{
display:block;
padding:3px 3px 3px 0.5em;
text-decoration:none;
border-left:28px solid #a71f1f;
border-right:1px solid #711515;
}
#navigation ul li ul li a:link, #navigation ul li ul li a:visited{
background-color:#e85070;
color:#FFFFFF;
}
#navigation ul li ul li a:hover{
background-color:#c2425d;
color:#ffff00;
}
#navigation ul li ul.myHide{ /* 隱藏子菜單 */
display:none;
}
#navigation ul li ul.myShow{ /* 顯示子菜單 */
display:block;
}
-->
</style>
<script language="javascript">
function change(){
//通過父元素li,找到兄弟元素ul
var oSecondDiv = this.parentNode.getElementsByTagName("ul")[0];
//CSS交替更換來實現(xiàn)顯、隱
if(oSecondDiv.className == "myHide")
oSecondDiv.className = "myShow";
else
oSecondDiv.className = "myHide";
}
window.onload = function(){
var oUl = document.getElementById("listUL"); //一級菜單的ul標(biāo)簽
var aLi = oUl.childNodes; //子元素
var oA;
for(var i=0;i<aLi.length;i++){
//如果子元素為li,且這個li有子菜單ul
if(aLi[i].tagName == "LI" && aLi[i].getElementsByTagName("ul").length){
oA = aLi[i].firstChild; //找到超鏈接
oA.onclick = change; //動態(tài)添加點擊函數(shù)
}
}
}
</script>
</head>
<body>
<div id="navigation">
<ul id="listUL">
<li><a href="#">Home</a></li>
<li><a href="#">News</a>
<ul class="myHide">
<li><a href="#">Lastest News</a></li>
<li><a href="#">All News</a></li>
</ul>
</li>
<li><a href="#">Sports</a>
<ul class="myHide">
<li><a href="#">Basketball</a></li>
<li><a href="#">Football</a></li>
<li><a href="#">Volleyball</a></li>
</ul>
</li>
<li><a href="#">Weather</a>
<ul class="myHide">
<li><a href="#">Today's Weather</a></li>
<li><a href="#">Forecast</a></li>
</ul>
</li>
<li><a href="#">Contact Me</a></li>
</ul>
</div>
</body>
</html>
上菜單為二級菜單,伸縮菜單是在一級菜單<li>下點擊實現(xiàn)的
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh-cn">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>伸縮菜單</title>
<meta name="keywords" content="關(guān)鍵字列表" />
<meta name="description" content="網(wǎng)頁描述" />
<link rel="stylesheet" type="text/css" href="" />
<style type="text/css">
body,p,ul,li{padding:0px;margin:0px;}
ul li{list-style:none;}
body{font-size:13px;}
.menu{
width:210px;
margin:50px auto;
border:1px solid #ccc;
}
.menu p{
height:25px;
line-height:25px;
font-weight:bold;
background:#eee;
border-bottom:1px solid #ccc;
padding-left:5px;
cursor:pointer;
}
.menu ul li{
height:24px;
line-height:24px;
padding-left:5px;
}
</style>
<script type="text/javascript">
//分析思路
//當(dāng)頁面加載完成后
//獲取到所有的p元素 獲取到所有的ul元素
//給每一個p元素綁定一個onclick事件
//判斷每一個p元素對應(yīng)的ul是否是隱藏或者是顯示
window.onload = function(){
//獲取id=menu對象
var div_obj = document.getElementById("menu");
//獲取所有的p元素
var ps_obj = div_obj.getElementsByTagName("p");
var ps_length = ps_obj.length;
//獲取到所有的ul元素
var uls_obj = div_obj.getElementsByTagName("ul");
//給每一個p元素綁定一個onclick事件
for(var i=0;i<ps_length;i++){
ps_obj[i].id = i; //給每一個p元素加上一個標(biāo)識
ps_obj[i].onclick = function(){
//判斷對應(yīng)的ul是否是顯示或者隱藏
if(uls_obj[this.id].style.display == "none"){
uls_obj[this.id].style.display = "block";
}else{
uls_obj[this.id].style.display = "none";
}
}
}
}
</script>
</head>
<body>
<div id="menu" class="menu">
<div>
<p>web前端</p>
<ul style="display:none;">
<li>HTML</li>
<li>DIV+CSS</li>
<li>JAVASCRIPT</li>
<li>jQuery</li>
<li>Bootstrap</li>
</ul>
</div>
<div>
<p>PHP+MYSQL核心編程</p>
<ul style="display:none;">
<li>PHP</li>
<li>MYSQL</li>
<li>HTTP協(xié)議</li>
<li>PHP繪圖技術(shù)</li>
</ul>
</div>
<div>
<p>PHP高級</p>
<ul style="display:none;">
<li>XML編程</li>
<li>AJAX</li>
<li>MVC</li>
</ul>
</div>
</div>
</body>
</html>
類似QQ伸縮菜單:
HPA全稱Horizontal Pod Autoscaler,即水平Pod自動伸縮器,可以根據(jù)觀察到的CPU、內(nèi)存使用率或自定義度量標(biāo)準(zhǔn)來自動增加或者減少Pod的數(shù)量,但是HPA不適用于無法擴、縮容的對象,例如DaemonSet,通常都作用與Deployment
HPA控制器會定期調(diào)整RC或者Deployment的副本數(shù),使對象數(shù)量符合用戶定義規(guī)則的數(shù)量
既然是通過CPU、內(nèi)存等指標(biāo)來自動擴、縮容Pod,那么HPA肯定是需要一個能監(jiān)控這些硬件資源的組件,則例的組件有很多選擇,例如metrices-server、Heapster等,這里使用metrices-server
metrices-server從api-server中獲取cpu、內(nèi)存使用率等監(jiān)控指標(biāo)
1、收集HPA控制下所有Pod最近的cpu使用情況(CPU utilization)
2、對比在擴容條件里記錄的cpu限額(CPUUtilization)
3、調(diào)整實例數(shù)(必須要滿足不超過最大/最小實例數(shù))
4、每隔30s做一次自動擴容的判斷
CPU utilization的計算方法是用cpu usage(最近一分鐘的平均值,通過metrics可以直接獲取到)除以cpu request(這里cpu request就是我們在創(chuàng)建容器時制定的cpu使用核心數(shù))得到一個平均值,這個平均值可以理解為:平均每個Pod CPU核心的使用占比。
k8s中的某個Metrics Server(Heapster或自定義Metrics Server)持續(xù)采集所有Pod副本的指標(biāo)數(shù)據(jù)。
HPA控制器通過Metrics Server的API(Heapster的API或聚合API)獲取這些數(shù)據(jù),基于用戶定義的擴縮容規(guī)則進行計算,得到目標(biāo)Pod副本數(shù)量。
當(dāng)目標(biāo)Pod副本數(shù)量與當(dāng)前副本數(shù)量不同時,HPA控制器就訪問Pod的副本控制器(Deployment 、RC或者ReplicaSet)發(fā)起scale操作,調(diào)整Pod的副本數(shù)量,完成擴縮容操作。
Master的kube-controller-manager服務(wù)持續(xù)監(jiān)測目標(biāo)Pod的某種性能指標(biāo),以計算是否需要調(diào)整副本數(shù)量。目前k8s支持的指標(biāo)類型如下。
◎ Pod資源使用率:Pod級別的性能指標(biāo),通常是一個比率值,例如CPU使用率。
◎ Pod自定義指標(biāo):Pod級別的性能指標(biāo),通常是一個數(shù)值,例如接收的請求數(shù)量。
◎ Object自定義指標(biāo)或外部自定義指標(biāo):通常是一個數(shù)值,需要容器應(yīng)用以某種方式提供,例如通過HTTP URL“/metrics”提供,或者使用外部服務(wù)提供的指標(biāo)采集URL。
k8s從1.11版本開始,棄用基于Heapster組件完成Pod的CPU使用率采集的機制,全面轉(zhuǎn)向基于Metrics Server完成數(shù)據(jù)采集。Metrics Server將采集到的Pod性能指標(biāo)數(shù)據(jù)通過聚合API(Aggregated API)如metrics.k8s.io、custom.metrics.k8s.io和external.metrics.k8s.io提供給HPA控制器進行查詢。關(guān)于聚合API和聚合器(API Aggregator)的概念我們后面詳細講解。
通過 伸縮系數(shù) 判斷是否要進行擴容或縮容。
HPA會根據(jù)獲得的指標(biāo)數(shù)值,應(yīng)用相應(yīng)的算法算出一個伸縮系數(shù),此系數(shù)是指標(biāo)的期望值與目前值的比值,如果大于1表示擴容,小于1表示縮容。
容忍度
--horizontal-pod-autoscaler-tolerance:容忍度
它允許一定范圍內(nèi)的使用量的不穩(wěn)定,現(xiàn)在默認為0.1,這也是出于維護系統(tǒng)穩(wěn)定性的考慮。
例如,設(shè)定HPA調(diào)度策略為cpu使用率高于50%觸發(fā)擴容,那么只有當(dāng)使用率大于55%或者小于45%才會觸發(fā)伸縮活動,HPA會盡力把Pod的使用率控制在這個范圍之間。
算法
具體的每次擴容或者縮容的多少Pod的算法為: 期望副本數(shù) = ceil[當(dāng)前副本數(shù) * ( 當(dāng)前指標(biāo) / 期望指標(biāo) )]
舉個栗子
當(dāng)前metric值是200m,期望值是100m,那么pod副本數(shù)將會翻一倍,因為 比率為 200.0 / 100.0 = 2.0;
如果當(dāng)前值是 50m ,我們會將pod副本數(shù)減半,因為 50.0 / 100.0 == 0.5
如果比率接近1.0,如0.9或1.1(即容忍度是0.1),將不會進行縮放(取決于內(nèi)置的全局參數(shù)容忍度,–horizontal-pod-autoscaler-tolerance,默認值為0.1)。
此外,存在幾種Pod異常的情況,如下所述。
◎ Pod正在被刪除(設(shè)置了刪除時間戳):將不會計入目標(biāo)Pod副本數(shù)量。
◎ Pod的當(dāng)前指標(biāo)值無法獲得:本次探測不會將這個Pod納入目標(biāo)Pod副本數(shù)量,后續(xù)的探測會被重新納入計算范圍。
◎ 如果指標(biāo)類型是CPU使用率,則對于正在啟動但是還未達到Ready狀態(tài)的Pod,也暫時不會納入目標(biāo)副本數(shù)量范圍。可以通過kube-controller-manager服務(wù)的啟動參數(shù)--horizontal-pod-autoscaler-initial-readiness-delay設(shè)置首次探測Pod是否Ready的延時時間,默認值為30s。另一個啟動參數(shù)--horizontal-pod-autoscaler-cpuinitialization-period設(shè)置首次采集Pod的CPU使用率的延時時間。
注意:
每次最大擴容pod數(shù)量不會超過當(dāng)前副本數(shù)量的2倍
如果某些pod的容器沒有需要的的資源metrics,自動伸縮將不會根據(jù)這些metrics進行伸縮。
如果指定了targetAverageValue 或者 targetAverageUtilization,currentMetricValue是所有目標(biāo)pod的metric取均值。在檢查容忍度和確定最終值之前,會結(jié)合參考pod是否就緒、是否丟失metrics。
設(shè)置了刪除時間戳的所有Pod(即處于關(guān)閉狀態(tài)的Pod)和所有失敗的Pod將被丟棄。
冷卻和延遲機制
使用HPA管理一組副本時,有可能因為metrics動態(tài)變化而導(dǎo)致副本數(shù)頻繁波動,這種現(xiàn)象叫做 “顛簸”。
想象一種場景:
當(dāng)pod所需要的CPU負荷過大,從而在創(chuàng)建一個新pod的過程中,系統(tǒng)的CPU使用量可能會同樣在有一個攀升的過程。所以,在每一次作出決策后的一段時間內(nèi),將不再進行擴展決策。對于擴容而言,這個時間段為3分鐘,縮容為5分鐘
-- horizontal-pod-autoscaler-downscale- delay :這個參數(shù)用于告訴autoscaler做完縮容操作后需要等多久才能進行下一次縮容,默認值是5分鐘。
--horizontal-pod-autoscaler-upscale-delay: 這個參數(shù)用于告訴autoscaler做完擴容操作后需要等多久才能進行下一次擴容,默認值是3分鐘。
注意:使用者需要知道調(diào)整這個參數(shù)可能造成的影響。設(shè)置得太長,HPA對負載變化的響應(yīng)也會變長;太短又會導(dǎo)致自動伸縮“顛簸”。
Pod延遲探測機制
如果指標(biāo)類型是CPU使用率,則對于正在啟動但是還未達到Ready狀態(tài)的Pod,也暫時不會納入目標(biāo)副本數(shù)量范圍。
可以通過kube-controller-manager服務(wù)的啟動參數(shù)--horizontal-pod-autoscaler-initial-readiness-delay設(shè)置首次探測Pod是否Ready的延時時間,默認值為30s。
另一個啟動參數(shù)--horizontal-pod-autoscaler-cpuinitialization-period設(shè)置首次采集Pod的CPU使用率的延時時間。
Kubernetes是借助Agrregator APIServer擴展機制來實現(xiàn)Custom Metrics。Custom Metrics APIServer是一個提供查詢Metrics指標(biāo)的API服務(wù)(Prometheus的一個適配器),這個服務(wù)啟動后,kubernetes會暴露一個叫custom.metrics.k8s.io的API,當(dāng)請求這個URL時,請求通過Custom Metics APIServer去Prometheus里面去查詢對應(yīng)的指標(biāo),然后將查詢結(jié)果按照特定格式返回。
要支持最新的custom(包括external)的metrics,也需要使用新版本的HPA:autoscaling/v2beta1,里面增加四種類型的Metrics:Resource、Pods、Object、External,每種資源對應(yīng)不同的場景,下面分別說明:
Resource支持k8s里Pod的所有系統(tǒng)資源(包括cpu、memory等),但是一般只會用cpu,memory因為不太敏感而且跟語言相關(guān):大多數(shù)語言都有內(nèi)存池及內(nèi)置GC機制導(dǎo)致進程內(nèi)存監(jiān)控不準(zhǔn)確。
Pods類型的metrics表示cpu,memory等系統(tǒng)資源之外且是由Pod自身提供的自定義metrics數(shù)據(jù),比如用戶可以在web服務(wù)的pod里提供一個promesheus metrics的自定義接口,里面暴露了本pod的實時QPS監(jiān)控指標(biāo),這種情況下就應(yīng)該在HPA里直接使用Pods類型的metrics。
Object類型的metrics表示監(jiān)控指標(biāo)不是由Pod本身的服務(wù)提供,但是可以通過k8s的其他資源Object提供metrics查詢,比如ingress等,一般Object是需要匯聚關(guān)聯(lián)的Deployment下的所有的pods總的指標(biāo)。
External類型的metrics也屬于自定義指標(biāo),與Pods和Object不同的是,其監(jiān)控指標(biāo)的來源跟k8s本身無關(guān),metrics的數(shù)據(jù)完全取自外部的系統(tǒng)。
在HPA最新的版本 autoscaling/v2beta2 中又對metrics的配置和HPA擴縮容的策略做了完善,特別是對 metrics 數(shù)據(jù)的目標(biāo)指標(biāo)值的類型定義更通用靈活:包括AverageUtilization、AverageValue和Value,但是不是所有的類型的Metrics都支持三種目標(biāo)值的,具體對應(yīng)關(guān)系如下表。
HPA里的各種類型的Metrics和Metrics Target Type的對應(yīng)支持關(guān)系表
先看個最簡單的HPA的定義的例子
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
從上面的例子可以看出,HPA的spec定義由三個必填部分組成:
HPA控制的目標(biāo)workload,即scaleTargetRef,理論上HPA可以對任意支持scale子接口( sub-resource )的workload做彈性伸縮,不過statefulset一般代表有狀態(tài)服務(wù),副本不可隨便修改,而Job一般代表短生命周期的,所以基本可以認為HPA目前是專門控制deployment的擴縮容的(不建議直接控制RS,否則將無法滾動升級)。
彈性擴縮容的上下邊界,minReplicas和maxReplicas,也就是說HPA的擴縮容也不能是漫無邊際,如果計算出的副本數(shù)超過max則統(tǒng)一取maxReplicas,maxReplicas是為了保護k8s集群的資源被耗盡,minReplicas則相反,而且minReplicas必須不大于maxReplicas,但是也要大于0(k8s v1.16之后才放開允許Objetct和External類型的metrics的minReplicas為0,需要apiserver開啟–feature-gates mapStringBool HPAScaleToZero=true),兩者相等就相當(dāng)于關(guān)閉了自動伸縮功能了,總的來說minReplicas和maxReplicas邊界機制避免metrics數(shù)據(jù)異常導(dǎo)致的副本數(shù)不受控,特別是HPA在k8s最新的v1.18版本也依然是alpha特性,強烈建議大家謹(jǐn)慎設(shè)置這兩個邊界。
metrics指標(biāo)類型和目標(biāo)值,在autoscaling/v1里只有targetCPUUtilizationPercentage,autoscaling/v2beta1開始就擴展為metrics數(shù)組了,也就是說一個HPA可以同時設(shè)置多個類型維度的metrics目標(biāo)指標(biāo),如果有多個HPA 將會依次考量各個指標(biāo),然后最終HPA Controller選擇一個會選擇擴縮幅度最大的那個為最終擴容副本數(shù)。在最新的autoscaling/v2beta2版本的HPA中,metrics type共有4種類型:Resource、Pods、Object、External,target里則定義了metrics的目標(biāo)期望值,這里target的type也有三種類型Utilization,AverageValue和 Value,不同的metrics type都只能支持部分target type(詳見上面表格)
此外,在autoscaling/v2beta2的HPA的spec里還新增了一個Behavior可選結(jié)構(gòu),它是用來精確控制HPA的擴容和縮容的速度。
完整的HPA的定義可參考k8s的官方API文檔。
默認HPA spec里不配置任何metrics的話k8s會默認設(shè)置cpu的Resouce,且目標(biāo)類型是AverageUtilization value為80%。
查看HPA所有版本
[root@master C]# kubectl api-versions |grep autoscaling
autoscaling/v1 #只支持通過CPU為參考依據(jù)來改變Pod的副本數(shù)
autoscaling/v2beta1 #支持通過CPU、內(nèi)存、連接數(shù)或者自定義規(guī)則為參考依據(jù)
autoscaling/v2beta2 #和v2beta1差不多
查看當(dāng)前版本
[root@master C]# kubectl explain hpa
KIND: HorizontalPodAutoscaler
VERSION: autoscaling/v1 #可以看到使用的默認版本是v1
DESCRIPTION:
configuration of a horizontal pod autoscaler.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
behaviour of autoscaler. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
status <Object>
current information about the autoscaler.
指定使用版本,這里并不是修改,相當(dāng)于執(zhí)行這條命令時,指定了下版本
[root@master C]# kubectl explain hpa --api-version=autoscaling/v2beta1
KIND: HorizontalPodAutoscaler
VERSION: autoscaling/v2beta1
DESCRIPTION:
HorizontalPodAutoscaler is the configuration for a horizontal pod
autoscaler, which automatically manages the replica count of any resource
implementing the scale subresource based on the metrics specified.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
metadata is the standard object metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
spec is the specification for the behaviour of the autoscaler. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.
status <Object>
status is the current information about the autoscaler.
[root@master kube-system]# kubectl top nodes #查看節(jié)點狀態(tài),因為沒有安裝,所以會報錯
Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
[root@master kube-system]# vim components-v0.5.0.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- pods
- nodes
- nodes/stats
- namespaces
- configmaps
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls
image: registry.cn-shenzhen.aliyuncs.com/zengfengjin/metrics-server:v0.5.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 4443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 200Mi
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-dir
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100
[root@master kube-system]# kubectl apply -f components-v0.5.0.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
#查看創(chuàng)建的pod
[root@master kube-system]# kubectl get pods -n kube-system| egrep 'NAME|metrics-server'
NAME READY STATUS RESTARTS AGE
metrics-server-5944675dfb-q6cdd 0/1 ContainerCreating 0 6s
#查看日志
[root@master kube-system]# kubectl logs metrics-server-5944675dfb-q6cdd -n kube-system
I0718 03:06:39.064633 1 serving.go:341] Generated self-signed cert (/tmp/apiserver.crt, /tmp/apiserver.key)
I0718 03:06:39.870097 1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I0718 03:06:39.870122 1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I0718 03:06:39.870159 1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I0718 03:06:39.870160 1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I0718 03:06:39.870105 1 requestheader_controller.go:169] Starting RequestHeaderAuthRequestController
I0718 03:06:39.871166 1 shared_informer.go:240] Waiting for caches to sync for RequestHeaderAuthRequestController
I0718 03:06:39.872804 1 dynamic_serving_content.go:130] Starting serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key
I0718 03:06:39.875741 1 secure_serving.go:197] Serving securely on [::]:4443
I0718 03:06:39.876050 1 tlsconfig.go:240] Starting DynamicServingCertificateController
I0718 03:06:39.970469 1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::client-ca-file
I0718 03:06:39.970575 1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file
I0718 03:06:39.971610 1 shared_informer.go:247] Caches are synced for RequestHeaderAuthRequestController
#如果報錯的化,可以修改apiserver的yaml文件,這是k8s的yaml文件
[root@master kube-system]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
40 - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
41 - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
42 - --enable-aggregator-routing=true #添加這行
43 image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.18.0
44 imagePullPolicy: IfNotPresent
#保存退出
[root@master kube-system]# systemctl restart kubelet #修改后重啟kubelet
#再次查看節(jié)點信息
[root@master kube-system]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 327m 4% 3909Mi 23%
node 148m 1% 1327Mi 8%
[root@master test]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
run: nginx
replicas: 1
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.2
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests: #想要HPA生效,必須添加requests聲明
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
run: nginx
spec:
ports:
- port: 80
selector:
run: nginx
[root@master test]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-9cb8d65b5-tq9v4 1/1 Running 0 14m 10.244.1.22 node <none> <none>
[root@master test]# kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP 172.16.169.27 <none> 80/TCP 15m
[root@master test]# kubectl describe svc nginx
Name: nginx
Namespace: default
Labels: run=nginx
Annotations: Selector: run=nginx
Type: ClusterIP
IP: 172.16.169.27
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.22:80
Session Affinity: None
Events: <none>
[root@node test]# curl 172.16.169.27 #訪問成功
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#創(chuàng)建一個cpu利用率達到20,最大10個pod,最小1個,這里沒有指定版本所以默認是v1版本,而v1版本只能以CPU為標(biāo)準(zhǔn)
[root@master test]# kubectl autoscale deployment nginx --cpu-percent=20 --min=1 --max=10
horizontalpodautoscaler.autoscaling/nginx autoscaled
#TARGETS可以看到使用率
[root@master test]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 0%/20% 1 10 1 86s
#創(chuàng)建一個測試pod增加負載,訪問地址要和pod的svc地址相同
[root@master ~]# kubectl run busybox -it --image=busybox -- /bin/sh -c 'while true; do wget -q -O- http://10.244.1.22; done'
#過一分鐘后看hap的使用率,REPLICAS是當(dāng)前pod的數(shù)量
[root@master test]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 27%/20% 1 10 5 54m
[root@master test]# kubectl get pods #再看pod數(shù)量,發(fā)現(xiàn)已經(jīng)增加到了5個
NAME READY STATUS RESTARTS AGE
bustbox 1/1 Running 0 119s
nginx-9cb8d65b5-24dg2 1/1 Running 0 57s
nginx-9cb8d65b5-c6n98 1/1 Running 0 87s
nginx-9cb8d65b5-ksjzv 1/1 Running 0 57s
nginx-9cb8d65b5-n77fm 1/1 Running 0 87s
nginx-9cb8d65b5-tq9v4 1/1 Running 0 84m
[root@master test]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 5/5 5 5 84m
#此時,停止壓測,過好幾分鐘后再次查看pod數(shù)量和使用率
[root@master test]# kubectl delete pod busybox #終止后,刪除pod
[root@master test]# kubectl get hpa #雖然使用率已經(jīng)降到0了,但是可以看到當(dāng)前REPLICAS的數(shù)量還5,這個需要等一會就會縮容
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 0%/20% 1 10 5 58m
#過了幾分鐘后,可以看到pod數(shù)量已經(jīng)回到了1
[root@master test]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 0%/20% 1 10 1 64m
[root@master test]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-9cb8d65b5-tq9v4 1/1 Running 0 95m
#先把上面創(chuàng)建的資源刪除
[root@master test]# kubectl delete horizontalpodautoscalers.autoscaling nginx
horizontalpodautoscaler.autoscaling "nginx" deleted
[root@master test]# kubectl delete -f nginx.yaml
deployment.apps "nginx" deleted
service "nginx" deleted
[root@master test]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
selector:
matchLabels:
run: nginx
replicas: 1
template:
metadata:
labels:
run: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.2
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
memory: 60Mi
requests:
cpu: 200m
memory: 25Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
run: nginx
spec:
ports:
- port: 80
selector:
run: nginx
[root@master test]# kubectl apply -f nginx.yaml
deployment.apps/nginx created
service/nginx created
[root@master test]# vim hpa-nginx.yaml
apiVersion: autoscaling/v2beta1 #上面的hpa版本有提到過,使用基于內(nèi)存的hpa需要換個版本
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
maxReplicas: 10 #1-10的pod數(shù)量限制
minReplicas: 1
scaleTargetRef: #指定使用hpa的資源對象,版本、類型、名稱要和上面創(chuàng)建的相同
apiVersion: apps/v1
kind: Deployment
name: nginx
metrics:
- type: Resource
resource:
name: memory
targetAverageUtilization: 50 #限制%50的內(nèi)存
[root@master test]# kubectl apply -f hpa-nginx.yaml
horizontalpodautoscaler.autoscaling/nginx-hpa created
[root@master test]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx 7%/50% 1 10 1 59s
更換終端測試
#在pod中執(zhí)行命令,增加內(nèi)存負載
[root@master ~]# kubectl exec -it nginx-78f4944bb8-2rz7j -- /bin/sh -c 'dd if=/dev/zero of=/tmp/file1'
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。