<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 集群及應用監控 在前面的[安裝heapster插件](heapster-addon-installation.md)章節,我們已經談到Kubernetes本身提供了監控插件作為集群和容器監控的選擇,但是在實際使用中,因為種種原因,再考慮到跟我們自身的監控系統集成,我們準備重新造輪子。 針對kubernetes集群和應用的監控,相較于傳統的虛擬機和物理機的監控有很多不同,因此對于傳統監控需要有很多改造的地方,需要關注以下三個方面: - Kubernetes集群本身的監控,主要是kubernetes的各個組件 - kubernetes集群中Pod的監控,Pod的CPU、內存、網絡、磁盤等監控 - 集群內部應用的監控,針對應用本身的監控 ## Kubernetes集群中的監控 ![Kubernetes集群中的監控](https://box.kancloud.cn/fcfe25dacfcb12995ce2879f2dbf1a84_978x539.png) 跟物理機器和虛擬機的監控不同,在kubernetes集群中的監控復雜度更高一些,因為多了一個虛擬化層,當然這個跟直接監控docker容器又不一樣,kubernetes在docker之上又抽象了一層service的概念。 在kubernetes中的監控需要考慮到這幾個方面: - 應該給Pod打上哪些label,這些label將成為監控的metrics。 - 當應用的Pod漂移了之后怎么辦?因為要考慮到Pod的生命周期比虛擬機和物理機短的多,如何持續監控應用的狀態? - 更多的監控項,kubernetes本身、容器、應用等。 - 監控指標的來源,是通過heapster收集后匯聚還是直接從每臺主機的docker上取? ## 容器的命名規則 首先我們需要清楚使用cAdvisor收集的數據的格式和字段信息。 當我們通過cAdvisor獲取到了容器的信息后,例如訪問`${NODE_IP}:4194/api/v1.3/docker`獲取的json結果中的某個容器包含如下字段: ```json "labels": { "annotation.io.kubernetes.container.hash": "f47f0602", "annotation.io.kubernetes.container.ports": "[{\"containerPort\":80,\"protocol\":\"TCP\"}]", "annotation.io.kubernetes.container.restartCount": "0", "annotation.io.kubernetes.container.terminationMessagePath": "/dev/termination-log", "annotation.io.kubernetes.container.terminationMessagePolicy": "File", "annotation.io.kubernetes.pod.terminationGracePeriod": "30", "io.kubernetes.container.logpath": "/var/log/pods/d8a2e995-3617-11e7-a4b0-ecf4bbe5d414/php-redis_0.log", "io.kubernetes.container.name": "php-redis", "io.kubernetes.docker.type": "container", "io.kubernetes.pod.name": "frontend-2337258262-771lz", "io.kubernetes.pod.namespace": "default", "io.kubernetes.pod.uid": "d8a2e995-3617-11e7-a4b0-ecf4bbe5d414", "io.kubernetes.sandbox.id": "843a0f018c0cef2a5451434713ea3f409f0debc2101d2264227e814ca0745677" }, ``` 這些信息其實都是kubernetes創建容器時給docker container打的`Labels`,使用`docker inspect $conainer_name`命令同樣可以看到上述信息。 你是否想過這些label跟容器的名字有什么關系?當你在node節點上執行`docker ps`看到的容器名字又對應哪個應用的Pod呢? 在kubernetes代碼中pkg/kubelet/dockertools/docker.go中的BuildDockerName方法定義了容器的名稱規范。 這段容器名稱定義代碼如下: ```go // Creates a name which can be reversed to identify both full pod name and container name. // This function returns stable name, unique name and a unique id. // Although rand.Uint32() is not really unique, but it's enough for us because error will // only occur when instances of the same container in the same pod have the same UID. The // chance is really slim. func BuildDockerName(dockerName KubeletContainerName, container *v1.Container) (string, string, string) { containerName := dockerName.ContainerName + "." + strconv.FormatUint(kubecontainer.HashContainerLegacy(container), 16) stableName := fmt.Sprintf("%s_%s_%s_%s", containerNamePrefix, containerName, dockerName.PodFullName, dockerName.PodUID) UID := fmt.Sprintf("%08x", rand.Uint32()) return stableName, fmt.Sprintf("%s_%s", stableName, UID), UID } // Unpacks a container name, returning the pod full name and container name we would have used to // construct the docker name. If we are unable to parse the name, an error is returned. func ParseDockerName(name string) (dockerName *KubeletContainerName, hash uint64, err error) { // For some reason docker appears to be appending '/' to names. // If it's there, strip it. name = strings.TrimPrefix(name, "/") parts := strings.Split(name, "_") if len(parts) == 0 || parts[0] != containerNamePrefix { err = fmt.Errorf("failed to parse Docker container name %q into parts", name) return nil, 0, err } if len(parts) < 6 { // We have at least 5 fields. We may have more in the future. // Anything with less fields than this is not something we can // manage. glog.Warningf("found a container with the %q prefix, but too few fields (%d): %q", containerNamePrefix, len(parts), name) err = fmt.Errorf("Docker container name %q has less parts than expected %v", name, parts) return nil, 0, err } nameParts := strings.Split(parts[1], ".") containerName := nameParts[0] if len(nameParts) > 1 { hash, err = strconv.ParseUint(nameParts[1], 16, 32) if err != nil { glog.Warningf("invalid container hash %q in container %q", nameParts[1], name) } } podFullName := parts[2] + "_" + parts[3] podUID := types.UID(parts[4]) return &KubeletContainerName{podFullName, podUID, containerName}, hash, nil } ``` 我們可以看到容器名稱中包含如下幾個字段,中間用下劃線隔開,至少有6個字段,未來可能添加更多字段。 下面的是四個基本字段。 ``` containerNamePrefix_containerName_PodFullName_PodUID ``` 所有kubernetes啟動的容器的containerNamePrefix都是k8s。 Kubernetes啟動的docker容器的容器名稱規范,下面以官方示例guestbook為例,Deployment 名為 frontend中啟動的名為php-redis的docker容器的副本書為3。 Deployment frontend的配置如下: ```yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: frontend spec: template: metadata: labels: app: guestbook tier: frontend spec: containers: - name: php-redis image: harbor-001.jimmysong.io/library/gb-frontend:v4 resources: requests: cpu: 100m memory: 100Mi env: - name: GET_HOSTS_FROM value: dns ports: - containerPort: 80 ``` 我們選取三個實例中的一個運行php-redis的docker容器。 ``` k8s_php-redis_frontend-2337258262-154p7_default_d8a2e2dd-3617-11e7-a4b0-ecf4bbe5d414_0 ``` - containerNamePrefix:k8s - containerName:php-redis - podFullName:frontend-2337258262-154p7 - computeHash:154p7 - deploymentName:frontend - replicaSetName:frontend-2337258262 - namespace:default - podUID:d8a2e2dd-3617-11e7-a4b0-ecf4bbe5d414 kubernetes容器命名規則解析,見下圖所示。 ![kubernetes的容器命名規則示意圖](https://box.kancloud.cn/d85d40f9abbb97e958834c361c68bb1a_1291x214.jpg) ## 使用Heapster進行集群監控 [Heapster](https://github.com/kubernetes/heapster)是kubernetes官方提供的監控方案,我們在前面的章節中已經講解了如何部署和使用heapster,見[安裝Heapster插件](../practice/heapster-addon-installation.md)。 但是Grafana顯示的指標只根據Namespace和Pod兩層來分類,實在有些單薄,我們希望通過應用的label增加service這一層分類。架構圖如下: ![Heapster架構圖(改進版)](https://box.kancloud.cn/bc38d9abcbaee9b1e33c21ca4e54bce5_1021x788.png) 在不改變原有架構的基礎上,通過應用的label來區分不同應用的pod。 ## 應用監控 Kubernetes中應用的監控架構如圖: ![應用監控架構圖](https://box.kancloud.cn/5148cb23e083bef01aeb1529bb6e1873_598x435.png) 這種方式有以下幾個要點: - 訪問kubernetes API獲取應用Pod的IP和端口 - Pod labels作為監控metric的tag - 直接訪問應用的Pod的IP和端口獲取應用監控數據 - metrics發送到[OWL](https://github.com/talkingdata/owl)中存儲和展示 ## 應用拓撲狀態圖 對于復雜的應用編排和依賴關系,我們希望能夠有清晰的圖標一覽應用狀態和拓撲關系,因此我們用到了Weaveworks開源的[scope](https://github.com/weaveworks/scope)。 **安裝scope** 我們在kubernetes集群上使用standalone方式安裝,詳情參考[Installing Weave Scope](https://www.weave.works/docs/scope/latest/installing/#k8s)。 使用[scope.yaml](https://github.com/rootsongjc/kubernetes-handbook/blob/master/manifests/weave/scope.yaml)文件安裝scope,該服務安裝在`kube-system` namespace下。 ```Bash $ kubectl apply -f scope.yaml ``` 創建一個新的Ingress:`kube-system.yaml`,配置如下: ```yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: traefik-ingress namespace: kube-system spec: rules: - host: scope.weave.io http: paths: - path: / backend: serviceName: weave-scope-app servicePort: 80 ``` 執行`kubectl apply -f kube-system.yaml`后在你的主機上的`/etc/hosts`文件中添加一條記錄: ``` 172.20.0.119 scope.weave.io ``` 在瀏覽器中訪問`scope.weave.io`就可以訪問到scope了,詳見[邊緣節點配置](edge-node-configuration.md)。 ![應用拓撲圖](https://box.kancloud.cn/874a71d06a80e8f81a939e60ab4f4d5c_1875x981.jpg) 如上圖所示,scope可以監控kubernetes集群中的一系列資源的狀態、資源使用情況、應用拓撲、scale、還可以直接通過瀏覽器進入容器內部調試等。 ## 參考 - [Monitoring in the Kubernetes Era](https://www.datadoghq.com/blog/monitoring-kubernetes-era/)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看