整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          CSS 伸縮動畫輸入框 #web前端

          天給大家帶來的是伸縮的輸入框的動畫。大家可以看到,點擊之后包括用戶名往上推,輸入框進行升高。其實這個在很多地方也可以用到,在實際項目中。長話短說,看代碼區域。

          我用開發工具是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概述

          1.1、HPAjieshao

          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.2、HPA伸縮過程

          1、收集HPA控制下所有Pod最近的cpu使用情況(CPU utilization)

          2、對比在擴容條件里記錄的cpu限額(CPUUtilization)

          3、調整實例數(必須要滿足不超過最大/最小實例數)

          4、每隔30s做一次自動擴容的判斷

          CPU utilization的計算方法是用cpu usage(最近一分鐘的平均值,通過metrics可以直接獲取到)除以cpu request(這里cpu request就是我們在創建容器時制定的cpu使用核心數)得到一個平均值,這個平均值可以理解為:平均每個Pod CPU核心的使用占比。

          1.3、HPA 的工作原理

          k8s中的某個Metrics Server(Heapster或自定義Metrics Server)持續采集所有Pod副本的指標數據。

          HPA控制器通過Metrics Server的API(Heapster的API或聚合API)獲取這些數據,基于用戶定義的擴縮容規則進行計算,得到目標Pod副本數量。

          當目標Pod副本數量與當前副本數量不同時,HPA控制器就訪問Pod的副本控制器(Deployment 、RC或者ReplicaSet)發起scale操作,調整Pod的副本數量,完成擴縮容操作。


          1.4、指標的類型

          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)的概念我們后面詳細講解。

          1.5、擴縮容策略

          通過 伸縮系數 判斷是否要進行擴容或縮容。

          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使用率的延時時間。

          1.6、HPA獲取自定義指標(Custom Metrics)的底層實現(基于Prometheus)

          Kubernetes是借助Agrregator APIServer擴展機制來實現Custom Metrics。Custom Metrics APIServer是一個提供查詢Metrics指標的API服務(Prometheus的一個適配器),這個服務啟動后,kubernetes會暴露一個叫custom.metrics.k8s.io的API,當請求這個URL時,請求通過Custom Metics APIServer去Prometheus里面去查詢對應的指標,然后將查詢結果按照特定格式返回。

          二、HPA的metrics的分類

          要支持最新的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的使用說明

          先看個最簡單的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部署

          4.1、HPA版本

          查看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.
          

          4.2、 HPA部署

          (1)部署metrics-server

          [root@master kube-system]# kubectl top nodes  #查看節點狀態,因為沒有安裝,所以會報錯
          Error from server (NotFound): the server could not find the requested resource (get services http:heapster:)
          • 編寫yaml文件,注意端口和鏡像
          [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%
          


          (2)創建Deployment

          • 這里創建一個nginx的deployment
          [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>
          

          (3)基于CPU創建HPA

          #創建一個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
          

          (4)基于內存創建的HPA

          #先把上面創建的資源刪除
          [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
          
          • 重新編寫yaml文件
          [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
          
          
          • 創建HPA
          [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'
          
          • 等待負載上去,然后查看pod數量與內存使用率

          主站蜘蛛池模板: 久久婷婷色一区二区三区| 亚洲一区精彩视频| 波多野结衣高清一区二区三区| 亚洲AV无码一区二区三区牛牛| 亚洲日韩国产一区二区三区在线 | 精品无码一区在线观看| 国产精品自拍一区| 日本精品视频一区二区| 国产一区三区三区| 亚洲高清一区二区三区| 成人免费视频一区二区| 无码成人一区二区| 国产精品日韩欧美一区二区三区| 色一情一乱一伦一区二区三区日本| 狠狠色婷婷久久一区二区| 激情内射亚洲一区二区三区爱妻| 国产成人一区二区三区电影网站| 一区国严二区亚洲三区| 亚洲av鲁丝一区二区三区| 亚洲精品无码一区二区| 人妻少妇AV无码一区二区| 波多野结衣久久一区二区| 国产激情一区二区三区 | 无码人妻精品一区二区三| 大香伊蕉日本一区二区| 国产在线无码一区二区三区视频| 亚洲性无码一区二区三区| 日本高清成本人视频一区| 人妻夜夜爽天天爽一区| 日本一区二区三区精品中文字幕| 日本香蕉一区二区三区| 国产午夜福利精品一区二区三区| 在线视频一区二区三区四区| 无码精品前田一区二区| 人妻少妇精品视频一区二区三区 | 日本精品夜色视频一区二区| 精品一区二区三区波多野结衣| 杨幂AV污网站在线一区二区| 亚洲国产欧美日韩精品一区二区三区| 精品人妻少妇一区二区| 日本一区中文字幕日本一二三区视频 |