天給大家帶來的是伸縮的輸入框的動畫。大家可以看到,點擊之后包括用戶名往上推,輸入框進行升高。其實這個在很多地方也可以用到,在實際項目中。長話短說,看代碼區域。
我用開發工具是hpdx開發uni app的,大家應該很熟悉了。vivo式組容器,可以看到里面包含了第二層vivo式組容器、important輸入框組件、文本組件,還有一條線。我用i來定義,就是這條線。這里面的有基礎同學可以知道,如果是真的時候是一個樣式,如果是假的時候另一個樣式互相切換的。
怎么在哪控制?通過input的定義了一下,在這使用type-c進行真假的切換。包括這兩個線條為什么會延伸高度?因為這地方定義了四十四px和二px,遇到真的時候是一種高度,遇到假時候是一種高度,這是動態的樣式,大家要記住。
css部分其實是很少的,就是靜態的、固定的。可以看到第一層優勢圖容器進行全局的定義,第二層就能相對定位和寬度的設置。輸入框的樣式進行相對定位,那邊去透明,文字顏色、字體大小等等。這地方也可以輸入文字,對文本也進行了央視的開發。大家可以看我這注釋,就是很詳細的。
進行線條的定義,就這三部分,大家可以看到,大概思路就這么個思路,大家可以動手去寫一下。
喜歡的同學可以點贊收藏,想要源代碼的可以找我嘮嗑進行獲取或者點擊下方都行,還是建議大家去動手去寫一下。今天推薦的伸縮版的輸入框的樣式就今天就講到這里,謝謝大家。
<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; /* 區塊顯示 */
padding:5px 5px 5px 0.5em;
text-decoration:none;
border-left:12px solid #711515; /* 左邊的粗紅邊 */
border-right:1px solid #711515; /* 右側陰影 */
}
#navigation > ul > li > a:link, #navigation > ul > li > a:visited{
background-color:#c11136;
color:#FFFFFF;
}
#navigation > ul > li > a:hover{ /* 鼠標經過時 */
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交替更換來實現顯、隱
if(oSecondDiv.className == "myHide")
oSecondDiv.className = "myShow";
else
oSecondDiv.className = "myHide";
}
window.onload = function(){
var oUl = document.getElementById("listUL"); //一級菜單的ul標簽
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; //動態添加點擊函數
}
}
}
</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>下點擊實現的
<!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="關鍵字列表" />
<meta name="description" content="網頁描述" />
<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">
//分析思路
//當頁面加載完成后
//獲取到所有的p元素 獲取到所有的ul元素
//給每一個p元素綁定一個onclick事件
//判斷每一個p元素對應的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元素加上一個標識
ps_obj[i].onclick = function(){
//判斷對應的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協議</li>
<li>PHP繪圖技術</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自動伸縮器,可以根據觀察到的CPU、內存使用率或自定義度量標準來自動增加或者減少Pod的數量,但是HPA不適用于無法擴、縮容的對象,例如DaemonSet,通常都作用與Deployment
HPA控制器會定期調整RC或者Deployment的副本數,使對象數量符合用戶定義規則的數量
既然是通過CPU、內存等指標來自動擴、縮容Pod,那么HPA肯定是需要一個能監控這些硬件資源的組件,則例的組件有很多選擇,例如metrices-server、Heapster等,這里使用metrices-server
metrices-server從api-server中獲取cpu、內存使用率等監控指標
1、收集HPA控制下所有Pod最近的cpu使用情況(CPU utilization)
2、對比在擴容條件里記錄的cpu限額(CPUUtilization)
3、調整實例數(必須要滿足不超過最大/最小實例數)
4、每隔30s做一次自動擴容的判斷
CPU utilization的計算方法是用cpu usage(最近一分鐘的平均值,通過metrics可以直接獲取到)除以cpu request(這里cpu request就是我們在創建容器時制定的cpu使用核心數)得到一個平均值,這個平均值可以理解為:平均每個Pod CPU核心的使用占比。
k8s中的某個Metrics Server(Heapster或自定義Metrics Server)持續采集所有Pod副本的指標數據。
HPA控制器通過Metrics Server的API(Heapster的API或聚合API)獲取這些數據,基于用戶定義的擴縮容規則進行計算,得到目標Pod副本數量。
當目標Pod副本數量與當前副本數量不同時,HPA控制器就訪問Pod的副本控制器(Deployment 、RC或者ReplicaSet)發起scale操作,調整Pod的副本數量,完成擴縮容操作。
Master的kube-controller-manager服務持續監測目標Pod的某種性能指標,以計算是否需要調整副本數量。目前k8s支持的指標類型如下。
◎ Pod資源使用率:Pod級別的性能指標,通常是一個比率值,例如CPU使用率。
◎ Pod自定義指標:Pod級別的性能指標,通常是一個數值,例如接收的請求數量。
◎ Object自定義指標或外部自定義指標:通常是一個數值,需要容器應用以某種方式提供,例如通過HTTP URL“/metrics”提供,或者使用外部服務提供的指標采集URL。
k8s從1.11版本開始,棄用基于Heapster組件完成Pod的CPU使用率采集的機制,全面轉向基于Metrics Server完成數據采集。Metrics Server將采集到的Pod性能指標數據通過聚合API(Aggregated API)如metrics.k8s.io、custom.metrics.k8s.io和external.metrics.k8s.io提供給HPA控制器進行查詢。關于聚合API和聚合器(API Aggregator)的概念我們后面詳細講解。
通過 伸縮系數 判斷是否要進行擴容或縮容。
HPA會根據獲得的指標數值,應用相應的算法算出一個伸縮系數,此系數是指標的期望值與目前值的比值,如果大于1表示擴容,小于1表示縮容。
容忍度
--horizontal-pod-autoscaler-tolerance:容忍度
它允許一定范圍內的使用量的不穩定,現在默認為0.1,這也是出于維護系統穩定性的考慮。
例如,設定HPA調度策略為cpu使用率高于50%觸發擴容,那么只有當使用率大于55%或者小于45%才會觸發伸縮活動,HPA會盡力把Pod的使用率控制在這個范圍之間。
算法
具體的每次擴容或者縮容的多少Pod的算法為: 期望副本數 = ceil[當前副本數 * ( 當前指標 / 期望指標 )]
舉個栗子
當前metric值是200m,期望值是100m,那么pod副本數將會翻一倍,因為 比率為 200.0 / 100.0 = 2.0;
如果當前值是 50m ,我們會將pod副本數減半,因為 50.0 / 100.0 == 0.5
如果比率接近1.0,如0.9或1.1(即容忍度是0.1),將不會進行縮放(取決于內置的全局參數容忍度,–horizontal-pod-autoscaler-tolerance,默認值為0.1)。
此外,存在幾種Pod異常的情況,如下所述。
◎ Pod正在被刪除(設置了刪除時間戳):將不會計入目標Pod副本數量。
◎ Pod的當前指標值無法獲得:本次探測不會將這個Pod納入目標Pod副本數量,后續的探測會被重新納入計算范圍。
◎ 如果指標類型是CPU使用率,則對于正在啟動但是還未達到Ready狀態的Pod,也暫時不會納入目標副本數量范圍。可以通過kube-controller-manager服務的啟動參數--horizontal-pod-autoscaler-initial-readiness-delay設置首次探測Pod是否Ready的延時時間,默認值為30s。另一個啟動參數--horizontal-pod-autoscaler-cpuinitialization-period設置首次采集Pod的CPU使用率的延時時間。
注意:
每次最大擴容pod數量不會超過當前副本數量的2倍
如果某些pod的容器沒有需要的的資源metrics,自動伸縮將不會根據這些metrics進行伸縮。
如果指定了targetAverageValue 或者 targetAverageUtilization,currentMetricValue是所有目標pod的metric取均值。在檢查容忍度和確定最終值之前,會結合參考pod是否就緒、是否丟失metrics。
設置了刪除時間戳的所有Pod(即處于關閉狀態的Pod)和所有失敗的Pod將被丟棄。
冷卻和延遲機制
使用HPA管理一組副本時,有可能因為metrics動態變化而導致副本數頻繁波動,這種現象叫做 “顛簸”。
想象一種場景:
當pod所需要的CPU負荷過大,從而在創建一個新pod的過程中,系統的CPU使用量可能會同樣在有一個攀升的過程。所以,在每一次作出決策后的一段時間內,將不再進行擴展決策。對于擴容而言,這個時間段為3分鐘,縮容為5分鐘
-- horizontal-pod-autoscaler-downscale- delay :這個參數用于告訴autoscaler做完縮容操作后需要等多久才能進行下一次縮容,默認值是5分鐘。
--horizontal-pod-autoscaler-upscale-delay: 這個參數用于告訴autoscaler做完擴容操作后需要等多久才能進行下一次擴容,默認值是3分鐘。
注意:使用者需要知道調整這個參數可能造成的影響。設置得太長,HPA對負載變化的響應也會變長;太短又會導致自動伸縮“顛簸”。
Pod延遲探測機制
如果指標類型是CPU使用率,則對于正在啟動但是還未達到Ready狀態的Pod,也暫時不會納入目標副本數量范圍。
可以通過kube-controller-manager服務的啟動參數--horizontal-pod-autoscaler-initial-readiness-delay設置首次探測Pod是否Ready的延時時間,默認值為30s。
另一個啟動參數--horizontal-pod-autoscaler-cpuinitialization-period設置首次采集Pod的CPU使用率的延時時間。
Kubernetes是借助Agrregator APIServer擴展機制來實現Custom Metrics。Custom Metrics APIServer是一個提供查詢Metrics指標的API服務(Prometheus的一個適配器),這個服務啟動后,kubernetes會暴露一個叫custom.metrics.k8s.io的API,當請求這個URL時,請求通過Custom Metics APIServer去Prometheus里面去查詢對應的指標,然后將查詢結果按照特定格式返回。
要支持最新的custom(包括external)的metrics,也需要使用新版本的HPA:autoscaling/v2beta1,里面增加四種類型的Metrics:Resource、Pods、Object、External,每種資源對應不同的場景,下面分別說明:
Resource支持k8s里Pod的所有系統資源(包括cpu、memory等),但是一般只會用cpu,memory因為不太敏感而且跟語言相關:大多數語言都有內存池及內置GC機制導致進程內存監控不準確。
Pods類型的metrics表示cpu,memory等系統資源之外且是由Pod自身提供的自定義metrics數據,比如用戶可以在web服務的pod里提供一個promesheus metrics的自定義接口,里面暴露了本pod的實時QPS監控指標,這種情況下就應該在HPA里直接使用Pods類型的metrics。
Object類型的metrics表示監控指標不是由Pod本身的服務提供,但是可以通過k8s的其他資源Object提供metrics查詢,比如ingress等,一般Object是需要匯聚關聯的Deployment下的所有的pods總的指標。
External類型的metrics也屬于自定義指標,與Pods和Object不同的是,其監控指標的來源跟k8s本身無關,metrics的數據完全取自外部的系統。
在HPA最新的版本 autoscaling/v2beta2 中又對metrics的配置和HPA擴縮容的策略做了完善,特別是對 metrics 數據的目標指標值的類型定義更通用靈活:包括AverageUtilization、AverageValue和Value,但是不是所有的類型的Metrics都支持三種目標值的,具體對應關系如下表。
HPA里的各種類型的Metrics和Metrics Target Type的對應支持關系表
先看個最簡單的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控制的目標workload,即scaleTargetRef,理論上HPA可以對任意支持scale子接口( sub-resource )的workload做彈性伸縮,不過statefulset一般代表有狀態服務,副本不可隨便修改,而Job一般代表短生命周期的,所以基本可以認為HPA目前是專門控制deployment的擴縮容的(不建議直接控制RS,否則將無法滾動升級)。
彈性擴縮容的上下邊界,minReplicas和maxReplicas,也就是說HPA的擴縮容也不能是漫無邊際,如果計算出的副本數超過max則統一取maxReplicas,maxReplicas是為了保護k8s集群的資源被耗盡,minReplicas則相反,而且minReplicas必須不大于maxReplicas,但是也要大于0(k8s v1.16之后才放開允許Objetct和External類型的metrics的minReplicas為0,需要apiserver開啟–feature-gates mapStringBool HPAScaleToZero=true),兩者相等就相當于關閉了自動伸縮功能了,總的來說minReplicas和maxReplicas邊界機制避免metrics數據異常導致的副本數不受控,特別是HPA在k8s最新的v1.18版本也依然是alpha特性,強烈建議大家謹慎設置這兩個邊界。
metrics指標類型和目標值,在autoscaling/v1里只有targetCPUUtilizationPercentage,autoscaling/v2beta1開始就擴展為metrics數組了,也就是說一個HPA可以同時設置多個類型維度的metrics目標指標,如果有多個HPA 將會依次考量各個指標,然后最終HPA Controller選擇一個會選擇擴縮幅度最大的那個為最終擴容副本數。在最新的autoscaling/v2beta2版本的HPA中,metrics type共有4種類型:Resource、Pods、Object、External,target里則定義了metrics的目標期望值,這里target的type也有三種類型Utilization,AverageValue和 Value,不同的metrics type都只能支持部分target type(詳見上面表格)
此外,在autoscaling/v2beta2的HPA的spec里還新增了一個Behavior可選結構,它是用來精確控制HPA的擴容和縮容的速度。
完整的HPA的定義可參考k8s的官方API文檔。
默認HPA spec里不配置任何metrics的話k8s會默認設置cpu的Resouce,且目標類型是AverageUtilization value為80%。
查看HPA所有版本
[root@master C]# kubectl api-versions |grep autoscaling
autoscaling/v1 #只支持通過CPU為參考依據來改變Pod的副本數
autoscaling/v2beta1 #支持通過CPU、內存、連接數或者自定義規則為參考依據
autoscaling/v2beta2 #和v2beta1差不多
查看當前版本
[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.
指定使用版本,這里并不是修改,相當于執行這條命令時,指定了下版本
[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 #查看節點狀態,因為沒有安裝,所以會報錯
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
#查看創建的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
#再次查看節點信息
[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>
#創建一個cpu利用率達到20,最大10個pod,最小1個,這里沒有指定版本所以默認是v1版本,而v1版本只能以CPU為標準
[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
#創建一個測試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是當前pod的數量
[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數量,發現已經增加到了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數量和使用率
[root@master test]# kubectl delete pod busybox #終止后,刪除pod
[root@master test]# kubectl get hpa #雖然使用率已經降到0了,但是可以看到當前REPLICAS的數量還5,這個需要等一會就會縮容
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 0%/20% 1 10 5 58m
#過了幾分鐘后,可以看到pod數量已經回到了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
#先把上面創建的資源刪除
[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版本有提到過,使用基于內存的hpa需要換個版本
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
maxReplicas: 10 #1-10的pod數量限制
minReplicas: 1
scaleTargetRef: #指定使用hpa的資源對象,版本、類型、名稱要和上面創建的相同
apiVersion: apps/v1
kind: Deployment
name: nginx
metrics:
- type: Resource
resource:
name: memory
targetAverageUtilization: 50 #限制%50的內存
[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中執行命令,增加內存負載
[root@master ~]# kubectl exec -it nginx-78f4944bb8-2rz7j -- /bin/sh -c 'dd if=/dev/zero of=/tmp/file1'
*請認真填寫需求信息,我們會在24小時內與您取得聯系。