kubernetes下heapster的部署案例

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本案例在我的部署环境下是可行的,但不保证在所有环境下都可行。我尽可能讲得直白而详细,因为我自己也才刚开始接触,已经做过深入研究的可以浏览,若有什么错误,烦请指正,感激不尽! 我的环境: K8S1.0.0+flannel+docker1.6的分布式集群。

本案例在我的部署环境下是可行的,但不保证在所有环境下都可行。我尽可能讲得直白而详细,因为我自己也才刚开始接触,已经做过深入研究的可以浏览,若有什么错误,烦请指正,感激不尽!

我的环境: K8S1.0.0+flannel+docker1.6的分布式集群。

这里先不赘述flannel的部署了,以后有时间再写 相关的文档。

1. ServiceAccount与Secret

先讲讲kubernetes的serviceaccount,我们的服务有时候需要一些带有隐私信息的东西,token,certification file等等,这些东西我们可以在master上创建,然后在创建pod的时候导入进去。具体可以去看github上的secret.md,那里有具体的例子。

我们执行:

kubectl get serviceaccount

如果如下:

NAME SECRETS
default 1 

那么是正常的(用脚本启动的kubernetes一般会是这样的情况) 而如果是:

NAME SECRETS
default 0 

这就麻烦了,用脚本启动k8s,启动的时候是会自动创建一个serviceaccount的,而serviceaccount创建出来的时候又会自动创建一个secret作为这个serviceaccount的token。

我们在apiserver的启动参数中添加:

--admission_control=ServiceAccount

apiserver在启动的时候会自己创建一个key和crt(见/var/run/kubernetes/apiserver.crtapiserver.key

然后在启动./kube-controller-manager 时添加flag:

--service_account_private_key_file=/var/run/kubernetes/apiserver.key

这样启动k8smaster后,我们就会发现

kubectl get serviceaccount

结果如下:

NAME SECRETS
default 1 

注意,这里可能会启动apiserver失败,或者启动后没有效果,因为没有secrets的serviceaccount会保存在etcd中,所以我们在正常启动前最好删掉etcd中的旧数据($etcdctl rm --recursive registry)。

正常启动后我们在这种状态下创建pod,pod中会加入serviceaccount这个字段,即便我们在创建的json或yaml中不指定,那么它的默认值也会是默认的serviceaccount:default。 而这个serviceaccount的secret就会被导入到pod启动的containers中。 举个例子,我们在这种状态下创建一个pod,然后执行:

[root@vm-56-65 bin]# kubectl get pods/imgpod -o yaml

在yaml中会发现:

spec: containers: - image: registry.hub.gome.com.cn/img_server:1.1 imagePullPolicy: IfNotPresent name: imgpod resources: limits: cpu: 600m memory: 1181116006400m terminationMessagePath: /dev/termination-log volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-n0i1i readOnly: true dnsPolicy: ClusterFirst nodeName: 10.58.56.62 restartPolicy: Always serviceAccountName: default volumes: - name: default-token-n0i1i secret: secretName: default-token-n0i1i 

有了serviceaccountName字段,并且volumn装载了一个secret.是的,这个secret:default-token-n0i1i就是我们default这个serviceaccount下的secret。它被装载到mountPath: /var/run/secrets/kubernetes.io/serviceaccount目录中,我们如果在slaver上进入相关容器,便可以找到这个目录和相应的token(注:创建这个pod的json中不用指定serviceaccount,也不用写volumn字段去挂载secret,这些都会自动完成的,是否可以手动指定呢?期待大神们的指点)。

为什么要先说这些呢? 因为我们的heapster启动的时候会有这种情况: pod状态为running,但是反复地restart;我们用webapi查看该pod的日志,发现:

/var/run/secret/kubernetes.io/serviceaccount/token no such file or directory

我认为这是因为heapster在运行时需要向k8smaster做https的连接,但是没有token和证书是不能连接的,heapster的程序找不到token就error并exit了,k8s会再启动之,于是就反复restart。

2.解决Heapster的Https访问问题

如下是我heapster启动的json(一个replicationcontroller)

heaprep.json:
{
 "apiVersion": "v1",
 "kind": "ReplicationController",
 "metadata": {
 "labels": {
 "name": "heapster"
 },
 "name": "monitoring-heapster-controller"
 },
 "spec": {
 "replicas": 1,
 "selector": {
 "name": "heapster"
 },
 "template": {
 "metadata": {
 "labels": {
 "name": "heapster"
 }
 },
 "spec": {
 "containers": [
 {
 "image": "registry.hub.gome.com.cn/kubernetes/heapster:v0.16.0",
 "name": "heapster",
 "command":[
 "/heapster",
 "--source=kubernetes:'https://kubernetes:443?auth='",
 "--sink=influxdb:http://10.126.53.10:8086"
 ],
 "resources": {
 "limits":{
 "cpu":"0.5",
 "memory":"1.1Gi"
 }
 },
 "env": [
 {
 "name": "KUBERNETES_SERVICE_HOST",
 "value": "vm-56-65"
 }
 ]
 }
 ]
 }
 }
 }
}

这里"env"中的环境变量是必须要加的,否则heapster会报错,具体什么错不大记得了,应该是有关10.0.0.1 这个域名的(heapster中的KUBERNETES_SERVICE_HOST变量默认是10.0.0.1)。 *10.0.0.1是k8s集群中master服务的ClusterIP(kubectl get svc 就可以看到),其他slaver是可以通过这个ip:port访问到master服务的。但是因为heapster做的是https的请求,需要crt证书和token。而10.0.0.1不是一个hostname并且没有相关的证书(感觉这是heapster最大的一个坑),所以我干脆自己做证书,自己做hosts引导,自己做环境变量。

现在我们需要一个hostname为vm-56-65的证书,执行这些命令:

openssl genrsa -out ca.key 2048

openssl req -x509 -new -nodes -key ca.key -subj "/CN=abc.com" -days 5000 -out ca.crt

openssl genrsa -out server.key 2048

openssl req -new -key server.key -subj "/CN=vm-56-65" -out server.csr

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000 

注意,这里两个 -subj "***"中第二个要写hostname,且强烈建议第一个subj和第二个不要相同(设为相同可能会导致普通的curl https命令认证失败)。具体关于证书的生成,可以参考: http://wangzhezhe.github.io/blog/2015/08/05/httpsandgolang/ 执行这些命令后,会生成一系列文件,将它们一并copy到master的/var/run/kubernetes/中,我们的master启动要用这些证书文件:

./kube-apiserver --logtostderr=true --log-dir=/var/log/ --v=0 --admission_control=ServiceAccount --etcd_servers=http://127.0.0.1:4001 --insecure_bind_address=0.0.0.0 --insecure_port=8080 --kubelet_port=10250 --service-cluster-ip-range=10.0.0.1/24 --allow_privileged=false --service-node-port-range='30000-35535' --secure-port=443 --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 

这里--secure-port=443 是因为我在heapster访问master时,没有采用内部ClusterIP,而是直接访问物理IP,而端口没有变,所以将master上apiserver的https监听端口修改了以便访问。

这样启动了apiserver后,我们再重新create pod。 容器启动,我们进入pod的日志,看到非常多的:

dial tcp: lookup vm-56-65: no such host

进入容器中修改容器里的/etc/hosts,添加一个:

10.58.56.65 vm-56-65 

如前文所说,我这里用了物理ip,当然,如果我们这里配10.0.0.1 也是可以的(如果使用10.0.0.1,api-server启动的时候就不用再添加--secure-port=443了)。 具体怎么进容器、改hosts这里我就不细讲了,大家都懂的~

修改完毕后,再刷新几次pod的日志,会发现,日志慢慢就不更新了(或者该说,不报错了),恭喜你,heapster已经在正常跑了。

不止如此,只要再添加一个token的配置,就可以在任何一台能与10.58.56.65直连的机器上,向apiserver做带认证的https请求。

heapster最大的好处是其抓取的监控数据可以按pod,container,namespace等方式group,这样就能进行监控信息的隐私化,即每个k8s的用户只能看到自己的应用的资源使用情况,而后台管理者又能看到每台机器的资源使用情况,类似自动扩容之类的功能就有了一个可靠的信息来源。

本文转自SegmentFault-kubernetes下heapster的部署案例

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
Kubernetes 持续交付 Docker
利用 Docker 和 Kubernetes 实现微服务部署
【10月更文挑战第2天】利用 Docker 和 Kubernetes 实现微服务部署
|
16天前
|
存储 Kubernetes 容器
K8S部署nexus
该配置文件定义了Nexus 3的Kubernetes部署,包括PersistentVolumeClaim、Deployment和服务。PVC请求20Gi存储,使用NFS存储类。Deployment配置了一个Nexus 3容器,内存限制为6G,CPU为1000m,并挂载数据卷。Service类型为NodePort,通过30520端口对外提供服务。所有资源位于`nexus`命名空间中。
|
3月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
148 60
|
3月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
280 62
|
2月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
3月前
|
Prometheus Kubernetes 监控
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
145 1
k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
|
2月前
|
存储 Kubernetes Devops
Kubernetes集群管理和服务部署实战
Kubernetes集群管理和服务部署实战
62 0
|
3月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
99 3
|
3月前
|
Kubernetes Docker 微服务
微服务实践k8s&dapr开发部署实验(1)服务调用(一)
微服务实践k8s&dapr开发部署实验(1)服务调用(一)
57 2
|
3月前
|
Kubernetes 网络安全 容器
基于Ubuntu-22.04安装K8s-v1.28.2实验(一)部署K8s
基于Ubuntu-22.04安装K8s-v1.28.2实验(一)部署K8s
366 2

热门文章

最新文章