Cloud Native Meetups
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Owners
          • Signed-in users
          • Everyone
          Owners Signed-in users Everyone
        • Write
          • Owners
          • Signed-in users
          • Everyone
          Owners Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Owners
    • Owners
    • Signed-in users
    • Everyone
    Owners Signed-in users Everyone
    Write
    Owners
    • Owners
    • Signed-in users
    • Everyone
    Owners Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ###### tags: `CKA` [讀書會入口](/ma8jxJEdRiSwwwboYtHuAg) # Scheduler(上) [TOC] ## Scheduling 簡介 Scheduling: 能把 pods 被配到某 Nodes 上,讓 kubelet 可以執行它 ### K8s Scheduler - K8s 裡面 default scheduler 就是 kube-scheduler - 是control-plane 的其中一個元件 - 也可以自定義 Scheduler <!-- 流程: 1. pod definition 初始化時,NodeName 預設為空 2. Scheduler 利用一系列function 計算 scoring 幫你找到最適合配置 pod 的 node 3. 告訴 api server 要把這個 pod bind 到哪個 node 上面 --> ![](https://i.imgur.com/qUrgz99.jpg) <!-- kube-scheduler 備份機制:Raft protocal --> ### Manual Scheduling 使用 binding + api requests 自行模擬 scheduler 的工作,配置 pod 要去的 node ![](https://i.imgur.com/7M41kh3.png) 如果 pod 無法調度,pod status 就會是變 pending ![](https://i.imgur.com/kizjXvY.png) ![](https://i.imgur.com/01ld9Hu.png) ## Label & Selectors #### Label - 綁定到 k8s 資源的 key/value pair - 可以加到各種Node, Pod, Service等資源上 - 方便 user 更好識別 回憶上集提過的 labels ``` "release" : "stable", "release" : "canary" "environment" : "dev", "environment" : "qa", "environment" : "production" "tier" : "frontend", "tier" : "backend", "tier" : "cache" "partition" : "customerA", "partition" : "customerB" "track" : "daily", "track" : "weekly" ``` 推薦使用的 labels <table> <thead> <tr> <th>Key</th> <th>Description</th> <th>Example</th> <th>Type</th> </tr> </thead> <tbody><tr> <td><a class="vglnk" href="http://app.kubernetes.io/name" rel="nofollow"><span>app</span><span>.</span><span>kubernetes</span><span>.</span><span>io</span><span>/</span><span>name</span></a></td> <td>Application 名稱</td> <td>mysql</td> <td>string</td> </tr> <tr> <td><a class="vglnk" href="http://app.kubernetes.io/instance" rel="nofollow"><span>app</span><span>.</span><span>kubernetes</span><span>.</span><span>io</span><span>/</span><span>instance</span></a></td> <td>Application Instance 的識別用名稱</td> <td>wordpress-abcxzy</td> <td>string</td> </tr> <tr> <td><a class="vglnk" href="http://app.kubernetes.io/version" rel="nofollow"><span>app</span><span>.</span><span>kubernetes</span><span>.</span><span>io</span><span>/</span><span>version</span></a></td> <td>Application目前的版本號</td> <td>5.7.21</td> <td>string</td> </tr> <tr> <td><a class="vglnk" href="http://app.kubernetes.io/component" rel="nofollow"><span>app</span><span>.</span><span>kubernetes</span><span>.</span><span>io</span><span>/</span><span>component</span></a></td> <td>在 Application 架構中的元件</td> <td>database</td> <td>string</td> </tr> <tr> <td><a class="vglnk" href="http://app.kubernetes.io/part-of" rel="nofollow"><span>app</span><span>.</span><span>kubernetes</span><span>.</span><span>io</span><span>/</span><span>part</span><span>-</span><span>of</span></a></td> <td>更上層的 Application 名稱</td> <td>wordpress</td> <td>string</td> </tr> <tr> <td><a class="vglnk" href="http://app.kubernetes.io/managed-by" rel="nofollow"><span>app</span><span>.</span><span>kubernetes</span><span>.</span><span>io</span><span>/</span><span>managed</span><span>-</span><span>by</span></a></td> <td>用來管理 Application 佈署 &amp; 操作的工具</td> <td>helm</td> <td>string</td> </tr> </tbody></table> ```yaml= apiVersion: apps/v1 kind: StatefulSet metadata: labels: app.kubernetes.io/name: mysql app.kubernetes.io/instance: mysql-abcxzy app.kubernetes.io/version: "5.7.21" app.kubernetes.io/component: database app.kubernetes.io/part-of: wordpress app.kubernetes.io/managed-by: helm ``` - 其他範例: 把這個 pod 加上 environment=production, app=nginx 的label ```yaml= apiVersion: v1 kind: Pod metadata: name: label-demo labels: environment: production app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` #### Selectors - 透過 selector, user 可以找出對應的set的物件 - K8s 主要的core grouping primitive - API支援兩種形式: - equality-based (=,==,!=) - set-based (in,notin and exists) ```bash # 逗號代表是 AND(&&)的意思 # equality-based kubectl get pods -l environment=production,tier=frontend # set-based kubectl get pods -l 'environment in (production),tier in (frontend)' # 組合使用 kubectl get pods -l 'partition in (customerA, customerB),environment!=qa' ``` **Field Selectors** 找 k8s 對應資源狀態的清單,例如 ``` metadata.name=my-service metadata.namespace!=default status.phase=Pending ``` ```bash= #取所有狀態是 Running 的 pod kubectl get pods --field-selector status.phase=Running #chained selectors kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always # 一次取多個resource type kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default ``` Q. 試想如果流量只要導到環境為python的http server? ![](https://i.imgur.com/Pf5nl0S.png) ```yaml apiVersion: v1 kind: Service metadata: name: service-example namespace: default spec: selector: svc: http-server env: python ports: - name: https port: 443 targetPort: 443 protocol: TCP ``` ## Assign Pods 到 Nodes 的方法 ### 1.Node Selectors 最簡單的選 node 設定條件方法, 會依據設定的 labels 配置 pod ```yaml= #選擇帶有 accelerator=nvidia-tesla-p100 標籤的node apiVersion: v1 kind: Pod metadata: name: cuda-test spec: containers: - name: cuda-test image: "registry.k8s.io/cuda-vector-add:v0.1" resources: limits: nvidia.com/gpu: 1 nodeSelector: accelerator: nvidia-tesla-p100 ``` ### 2.Taints(污點) & Tolerations(容忍) ![](https://i.imgur.com/zSO8bQ4.png) 可以Taint Node,確保不會有不適合的pod 被配置到指定node 設定 Pod Tolerations, 讓 pod 也可以被配置到有 taint 的node 兩個搭配確保 pod 不會配到不適合的 node 上 **對node設定** - 給key/value pair,並指定 effect - 可以對一個node有多個taints - effect: `NoSchedule`: 不 match label 就不會配到 node 上 `PreferNoSchedule`: 比較 soft 的 NoSchedule, K8s 會避免把不相容的 pod 放到 node 上 `NoExecute`: 強制踢出,一旦 taint 生效,如果 Node 裡面正在運行的 pod 沒有對應 Tolerate 設定,就會被逐出 ```bash # set taint to node # 除非 pod 有相符的label, 否則不會assign 到node1 kubectl taint nodes node1 disk=ssd:NoSchedule # delete taint on node kubectl taint nodes node1 disk- ``` **對 pod 的設定** ```yaml= tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" ``` 使用時機: 1. 專屬某特定使用的 Node `kubectl taint nodes nodename dedicated=groupName:NoSchedule` 2. 有特殊硬體的 Node `kubectl taint nodes nodename special=true:NoSchedule` or `kubectl taint nodes nodename special=true:PreferNoSchedule` 3. Taint based Evictions 當 node 有問題時,可以針對 pod-level 設定 eviction behavior 像是 node controller 就有 build-in 的 taint, 例如: - node.kubernetes.io/not-ready: Node is not ready. This corresponds to the NodeCondition Ready being "False". - node.kubernetes.io/unreachable: Node is unreachable from the node controller. This corresponds to the NodeCondition Ready being "Unknown". - node.kubernetes.io/memory-pressure: Node has memory pressure. ```yaml= # tolerationSeconds define 她還可以待在這個不適合的pod多久 tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600 ``` ### 3.Affinity(親和力) k8s最早只有Node Selector,Affinity是後面的版本才加進來的,延伸了可以定義的條件。 好處: - affinity/anti-affinity 更好表現選擇邏輯 - 指定 rule 是 soft/preferred, 條件不 match 還是可以配置 pod - 利用運行在 node 上 pod 存在的 label 限制要配置的 pod,可以讓你定義哪些 pod 可以一起配在同個 node 用法: `requiredDuringSchedulingIgnoredDuringExecution`: 除非條件符合否則不會 Schedule pod,跟 `nodeSelector`類似。 `preferredDuringSchedulingIgnoredDuringExecution`: 試著找到對應的 node ,但如果條件不 match,還是會 schedule. ```yaml= apiVersion: v1 kind: Pod metadata: name: nginx spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: disktype operator: In values: - ssd containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent ``` ### Taints & Tolerations vs Affinity | Taint & Tolerations| Affinity (親和力) | | -------- | -------- | | 確保 node 資源被指定的 pod 使用 | 確保 pod 在配置時能被配到希望使用的 node | ## k8s-scheduler 機制 拿 create pod 流程舉例: 1. api server 先將create pod 資料寫入 etcd 2. Scheduler 知道有沒 assign Node 的 pod 3.算出結果後回 NodeName 給 api server 4. 結果 bind 回 pod definition / etcd 紀錄 5. kubelet 接手起pod ![](https://i.imgur.com/lNae96O.png) (https://harshanarayana.dev/2020/06/writing-a-custom-kubernets-scheduler/) 那 Scheduler 到底怎麼選出要配在哪個 pod 的? ![](https://i.imgur.com/j2Azzlh.png) 如果 pod 中有指定 NodeName 則不用 Scheduler 參與,直接被調度到指定節點 ![](https://i.imgur.com/d3cc9uO.png) ### kube-scheduler 利用兩步驟選擇適合的 node 利用 Scheduling Policies , Scheduling Profiles 實現 1. Filtering: predicates 2. Scoring: priority 後來Scheduling 又有了 Scheduling framework,是個 pluggable architecture for k8s scheduler. 分為 Scheduling Cycle (依序執行), Binding Cycle (可同時執行). ![](https://i.imgur.com/WEbPzl2.png) ### QueueSort 用來排序在 Scheduling queue 裡面的 pod, 一次只能 enable 一個 ### Filter - nodeSelector - nodeAffinity - affinitfy, anti-affinity Scheduler 中,可選的Predicates ![](https://i.imgur.com/Rbw2OiA.png) ### Score Scheduler 中,可選的Priotity ![](https://i.imgur.com/EwwMwPS.png) ![](https://i.imgur.com/ZCFkFLq.png) --- **其他擴展點:** `QueueSort`: 用在調度序列排序, 一次只有一個調度器Plugin可以運作 `PreFilter`: 在Pod調度前先對cluster或pod進行的檢查, 一個調度週期只會做一次, 如果檢查失敗會中斷調度 `Filter`: 過濾不能運行Pod的節點 `PostFilter`: 節點預選後調用的, 可以用來記錄log `PreScore`: 預先針對調度節點打分數, 如果檢查失敗會中斷調度 `Score`: 根據配置的權重針對調度節點打分數 `NormalizeScore`: 在結算節點排名之前修改節點分數, 如果檢查失敗會中斷調度 `Reserve`: 為防止資源競爭需要先幫選定的Pod預留節點上的資源 `Permit`: 針對Pod綁定前檢查或是延遲Pod綁定 `approve`: 所有Permit Plugin檢查成功後就將Pod發送出去綁定 `deny`: 只要有Permit Plugin檢查失敗, 就將Pod退回到調度序列, 並調用Unreserve `wait`: 如果有Permit Plugin返回等待中, Pod的週期就會一直停在等待的狀態, 如果在超時前都無法完成則會進行deny的流程 `PreBind`: 在Pod綁定到節點之前執行 `Bind`: 在所有PreBind都執行完後才執行 `PostBind`: Pod成功綁定後才執行, 是綁定(Binding Cycle)的最後一個擴展點 `Unreserve`: Pod保留後被拒絕才會執行 ## Reference - Udemy - K8s官方文件 - https://ithelp.ithome.com.tw/articles/10221929 - https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/ - confluence - 啓維的DE talk ### 討論項目: Watch 通过 HTTP 协议与 Kubernetes API Server 建立长连接,接收 Kubernetes API Server 发来的资源变更事件。Watch 操作的实现机制使用 HTTP 协议的分块传输编码——当 client-go 调用 Kubernetes API Server 时,Kubernetes API Server 在 Response 的 HTTP Header 中设置 Transfer-Encoding 的值为 chunked,表示采用分块传输编码,客户端收到消息后,与服务端进行连接,并等待下一个数据块。 - https://cloudnative.to/blog/client-go-informer-source-code/#%E6%80%BB%E7%BB%93 - https://github.com/k8s-club/k8s-club/blob/main/articles/Informer%E6%9C%BA%E5%88%B6%20-%20%E6%A6%82%E8%BF%B0.md

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully