在 Kubernetes 系统中,使用 cAdvisor 对 Node 所在主机资源和在该 Node 上运行的容器进行监控和性能数据采样。由于 cAdvisor 集成在 Kubelet 中,即运行在每个 Node 上,所以一个 cAdvisor 仅能对一台 Node 进行监控。在大规模容器集群中,我们需要对所有 Node 和全部容器进行性能监控,Kubernetes 使用一套工具来实现集群性能数据的采集、存储和展示:Heapster、InfluxDB 和 Grafana。
Heapster:是对集群中各 Node、Pod 的资源使用数据进行采集的系统,通过访问每个 Node 上 Kubelet 的 API,再通过 Kubelet 调用 cAdvisor 的 API 来采集该节点上所有容器的性能数据。之后 Heapster 进行数据聚合,并将结果保存到后端存储系统中。Heapster 支持多种后端存储系统,包括 memory、InfluxDB、BigQuery、谷歌云平台提供的 Google Cloud Monitoring 和 Google Cloud Logging等。
InfluxDB:是分布式时序数据库(每条记录都带有时间戳属性),主要用于实时数据采集、事件跟踪记录、存储时间图标、原始数据等。InfluxDB 提供 REST API 用于数据的存储和查询。
Grafana:通过 Dashboard 将 InfluxDB 中的时序数据展现成图标或曲线等形式,便于运维人员查看集群的运行状态。
配置 Kubernetes 集群的 ServiceAccount 和 Secret
Heapster 当前版本需要使用 HTTPS 的安全方式与 Kubernetes Master 进行连接,所以需要先进行 ServiceAccount 和 Secret 的创建。如果不使用 Secret,则 Heapster 启动时将会报错,然后 Heapster 容器会被 ReplicationController 反复销毁、创建,无法正常工作。
关于 ServiceAccount 和 Secret 的原理详见http://blog.dingmingk.com/blog/kube_security.html。
在进行一下操作时,我们假设在 Kubernetes 集群中没有创建过 Secret(如果之前创建过,则可以先删除 etcd 中与 Secret 相关的键值)。
首先,使用 OpenSSL 工具在 Master 服务器上创建一些证书和私钥相关的文件:
1 2 3 4 5
| # openssl genrsa -out ca.key 2048 # openssl req -x509 -new -nodes -key ca.key -subj "/CN=yourcompany.com" -days 5000 -out ca.crt # openssl genrsa -out server.key 2048 # openssl req -new -key server.key -subj "/CN=kubernetes-master" -out server.csr # openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
|
注意,在生成 server.csr 时 -subj 参数中 /CN 指定的名字需为 Master 的主机名。另外,在生成 ca.crt 时 -subj 参数中 /CN 的名字最好与主机名不同,设为相同可能导致对普通 Master 的 HTTPS 访问认证失败。
执行完成后会生成 6 个文件:ca.crt、ca.key、ca.srl、server.crt、server.csr、server.key。将这些文件复制到 /var/run/kubernetes/ 目录中,然后设置kube-apiserver 的启动参数:
1 2 3
| --client_ca_file=/var/run/kubernetes/ca.crt --tls-private-key-file=/var/run/kubernetes/server.key --tls-cert-file=/var/run/kubernetes/server.crt
|
之后重启 kube-apiserver 服务。
接下来,给 kube-controller-manager 服务添加以下启动参数:
1 2
| --service_account_private_key_file=/var/run/kubernetes/server.key --root-ca-file=/var/run/kubernetes/ca.crt
|
然后重启 kube-controller-manager 服务。
在 kube-apiserver 服务成功启动后,系统会自动为每个命名空间创建一个 ServiceAccount 和一个 Secret(包含一个 ca.crt 和一个 token):
1 2 3
| $ kubectl get serviceaccounts --all-namespaces $ kubectl get secrets --all-namespaces $ kubectl describe secret xxx
|
之后 ReplicationController 在创建 Pod 时,会生成类型为 Secret 的 Volume 存储卷,并将该 Volume 挂载到 Pod 内的如下目录中:/var/run/secrets/kubernetes.io/serviceaccount。然后,容器内的应用程序就可以使用该 Secret 与 Master 建立 HTTPS 连接了。Pod 的 Volumes 设置和挂载操作由 ReplicationController 和 Kubelet 自动完成,可以通过查看 Pod 的详细信息了解到。
1
| $ kubectl get pods kube-dns-v8-xxxxx --namespace=kube-system -o yaml
|
进入容器,查看/var/run/secrets/kubernetes.io/serviceaccount 目录,可以看到两个文件 ca.crt 和 token,这两个文件就是与 Master 通信时所需的证书和秘钥信息。
部署 Heapster、InfluxDB、Grafana
在 ServiceAccount 和 Secrets 创建完成后,我们就可以创建 Heapster、InfluxDB 和 Grafana 等 ReplicationController 和 Service 了。
heapsster-service.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: v1 kind: Service metadata: labels: kubernetes.io/cluster-service: "true" kubernetes.io/name: Heapster name: heapster namespace: kube-system spec: ports: - port: 80 targetPort: 8082 selector: k8s-app: heapster
|
InfluxDB-service.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| apiVersion: v1 kind: Service metadata: labels: null name: monitoring-InfluxDB namespace: kube-system spec: type: NodePort ports: - name: http port: 8083 targetPort: 8083 nodePort: 30083 - name: api port: 8086 targetPort: 8086 nodePort: 30086 selector: name: influxGrafana
|
Grafana-service.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: v1 kind: Service metadata: labels: kubernetes.io/name: monitoring-Grafana kubernetes.io/cluster-service: "true" name: monitoring-Grafana namespace: kube-system spec: type: NodePort ports: - port: 80 targetPort: 8080 nodePort: 30080 selector: name: influxGrafana
|
heapster-controller.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: v1 kind: ReplicationController metadata: labels: k8s-app: heapster name: heapster version: v6 name: heapster namespace: kube-system spec: replicas: 1 selector: name: heapster k8s-app: heapster version: v6 template: metadata: labels: k8s-app: heapster version: v6 spec: containers: - name: heapster image: gcr.io/google_containers/heapster:v0.17.0 command: - /heapster - --source=kubernetes:http://192.168.1.128:8080?inClusterConfig=false&kubeletHttps=true&useServiceAccount=true&auth= - --sink=InfluxDB:http://monitoring-InfluxDB:8086
|
Heapster 需要设置的参数如下:
- –source:为配置监控来源。在本例中使用 kubernetes:表示从 Kubernetes Master 获取各 Node 的信息。在 URL 后面的参数部分,修改 kubeletHttps、inClusterConfig、useServiceAccount 的值,并设置 auth 的值为空。URL中可配置的参数如下:
- IP 地址和端口号:为 Kubernetes Master 的地址。
- kubeletPort:默认为 10255(Kubelet 服务的只读端口号)。
- kubeletHttps:是否通过 HTTPS 方式连接 Kubelet,默认为 false。
- apiVersion: API 版本号,默认为 Kubernetes 系统的版本号,当前为 v1.
- inClusterConfig:是否使用 Heapster 命名空间中的 ServiceAccount,默认为 true。
- insecure:是否信任 Kubernetes 证书,默认为 false。
- auth:客户端认证授权文件,当 ServiceAccount 不可用时对其进行设置。
- useServiceAccount:是否使用 ServiceAccount,默认为 false。
- –sink:为配置后端的存储系统,在本例中使用 InfluxDB 系统。
InfluxDB-Grafana-controller.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| apiVersion: v1 kind: ReplicationController metadata: labels: name: influxGrafana name: infludb-Grafana namespace: kube-system spec: replicas: 1 selector: name: influxGrafana template: metadata: labels: name: influxGrafana spec: containers: - name: InfluxDB image: gcr.io/google_containers/heapster_InfluxDB:v0.3 ports: - containerPort: 8083 hostPort: 8083 - containerPort: 8086 hostPort: 8086 - name: Grafana image: gcr.io/google_containers/heapster_Grafana:v0.7 ports: - containerPort: 8080 hostPort: 8080 env: - name: INFLUXDB_HOST value: monitoring-InfluxDB
|
最后,创建所有 Service 和 RC:
1 2 3 4 5
| $ kubectl create -f heapster-service.yaml $ kubectl create -f InfluxDB-server.yaml $ kubectl create -f Grafana-service.yaml $ kubectl create -f InfluxDB-Grafana-controller.yaml $ kubectl create -f heapster-controller.yaml
|
通过 kubectl get pods –namespace=kube-system 确认各 Pod 都成功启动了。