首页
常用命令
About Me
推荐
weibo
github
Search
1
linuxea:gitlab-ci之docker镜像质量品质报告
48,736 阅读
2
linuxea:如何复现查看docker run参数命令
19,340 阅读
3
Graylog收集文件日志实例
17,774 阅读
4
linuxea:jenkins+pipeline+gitlab+ansible快速安装配置(1)
17,316 阅读
5
git+jenkins发布和回滚示例
17,312 阅读
ops
Openvpn
Sys Basics
rsync
Mail
NFS
Other
Network
HeartBeat
server 08
Code
Awk
Shell
Python
Golang
virtualization
KVM
Docker
openstack
Xen
kubernetes
kubernetes-cni
Service Mesh
Data
Mariadb
PostgreSQL
MongoDB
Redis
MQ
Ceph
TimescaleDB
kafka
surveillance system
zabbix
ELK Stack
Open-Falcon
Prometheus
Web
apache
Tomcat
Nginx
自动化
Puppet
Ansible
saltstack
Proxy
HAproxy
Lvs
varnish
更多
音乐
影视
music
Internet Consulting
最后的净土
软件交付
持续集成
gitops
devops
登录
Search
标签搜索
kubernetes
docker
zabbix
Golang
mariadb
持续集成工具
白话容器
linux基础
nginx
elk
dockerfile
Gitlab-ci/cd
最后的净土
基础命令
jenkins
docker-compose
gitops
haproxy
saltstack
GitLab
marksugar
累计撰写
672
篇文章
累计收到
140
条评论
首页
栏目
ops
Openvpn
Sys Basics
rsync
Mail
NFS
Other
Network
HeartBeat
server 08
Code
Awk
Shell
Python
Golang
virtualization
KVM
Docker
openstack
Xen
kubernetes
kubernetes-cni
Service Mesh
Data
Mariadb
PostgreSQL
MongoDB
Redis
MQ
Ceph
TimescaleDB
kafka
surveillance system
zabbix
ELK Stack
Open-Falcon
Prometheus
Web
apache
Tomcat
Nginx
自动化
Puppet
Ansible
saltstack
Proxy
HAproxy
Lvs
varnish
更多
音乐
影视
music
Internet Consulting
最后的净土
软件交付
持续集成
gitops
devops
页面
常用命令
About Me
推荐
weibo
github
搜索到
71
篇与
kubernetes
的结果
2018-12-17
linuxea:kubernetes 了解chart(51)
在helm的体系中,有helm,tiller server,以及chart。tiller作为服务端一般运行在k8s集群之上,helm能够通过tiller server在k8s之上部署应用程序,这些应用程序来在helm能够访问到的仓库当中的chart。此前我们自定义了一些简单的值文件,实现实例化chart可安装的,可运行的release。也可以通过chart生成release,其中配置文件config来自chart中的values.yaml文件。对于chart来讲,事实上内部没有太复杂的地方,只是将此前我们所使用的编写的配置清单,改写为可复用的格式。此前我们的配置清单的都是为了完成某一个特定的功能而开发,一旦编辑完成,如果需要配置变更就需要重新修改配置清单文件,或者重新更新配置文件。而helm chart引用了一种机制,能够把此前配置清单中特定的内容,尤其是属性值,配置为模板内容。这类似于ansibel当中的playbook模板。只不过其中调用的变量值来自于不同的位置,或是helm内建的,或者是来自部署的release,也有一些属性值是由用户通过值文件(config)提供。chart组成我们先获取一个chart[root@linuxea helm]# helm fetch stable/redis [root@linuxea helm]# ls redis-4.2.10.tgz values.yaml这些文件在打包的时候将时间改为unix元年的时间[root@linuxea helm]# tar xf redis-4.2.10.tgz tar: redis/Chart.yaml: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/values.yaml: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/templates/NOTES.txt: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/templates/_helpers.tpl: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/templates/configmap.yaml: implausibly old time stamp 1970-01-01 01:00:00一个chart组成部分:https://docs.helm.sh/developing_charts/#the-chart-file-structure,翻译如下wordpress/ Chart.yaml #YAML文件,包含有关chart的信息,名称,版本等等信息 LICENSE #OPTIONAL:包含chart许可证的纯文本文件 README.md #OPTIONAL:一个人类可读的README文件 requirements.yaml #OPTIONAL:列出chart依赖关系的YAML文件。如,lnmp的依赖关系。自动处理依赖 values.yaml #此chart的默认配置值。对模板中自定义变量的引用设定的默认值。 charts/ #包含此chart所依赖的任何chart的目录。charts于requirements类似。目录下存放每一个被当前charts所依赖的其他的charts的打包tgz格式文件。一旦tgz存放在此处,就会被依赖。不管requirements是否存在。手动依赖关系 templates/ #模板目录,当与值组合时。这取决于模板的语法,比如清单中定义的service,pvc等,这些便于复用的属性或者字段就会改造成能够通过模板编程语言,基于模板编程结果生成的信息并且自动替换到代码所在处。这需要对go模板语法理解。 #将生成有效的Kubernetes清单文件。 templates/NOTES.txt #OcTIONAL:包含简短使用说明的纯文本文件redis文件树如下:yaml定义chartapiVersion:chartAPI版本,始终为“v1”(必填) name:chart的名称(必填),与目录名称保持一致 Version:SemVer 2版本(必填),版本格式 kubeVersion:SemVer系列兼容的Kubernetes版本(可选) description:该项目的单句描述(可选) keywords: - 关于此项目的关键字列表(可选) home:该项目主页的URL(可选) sources: - 此项目源代码的URL列表(可选) maintainers:#(可选) - name:维护者的名字(每个维护者都需要) email:维护者的电子邮件(每个维护者可选) url:维护者的URL(每个维护者可选) engine:gotpl#模板引擎的名称(可选,默认为gotpl) icon:要用作图标的SVG或PNG图像的URL(可选)。 appVersion:包含的应用程序版本(可选)。这不一定是SemVer。 deprecated:是否弃用此chart(可选,布尔值) tillerVersion:此chart所需的Tiller版本。这应该表示为SemVer范围:“> 2.0.0”(可选)requirementsdependencies: - name: apache version: 1.2.3 repository: http://example.com/charts - name: mysql version: 3.2.1 repository: http://another.example.com/charts在dependencies中会引用一个列表,每一个列表是一个对象,每一个对象就定义一个被依赖的chart该name字段是您想要的chart的名称。该version字段是您想要的chart的版本。该repository字段是chart存储库的完整URL。请注意,您还必须使用helm repo add在本地添加该repo。打包一个当前的chart,就会分析requirements文件语法格式,将每一个依赖的chart从指定的仓库中下载至本地完成打包。运行helm dependency update CHARTS_NAME ,将使用的requirements文件将所有指定的依赖项下载到charts/目录中。这样在执行一个应用的时候,打包内的依赖都被自动安装完成。当然,如果我此前已知依赖关系,只需要将依赖的包下载到charts目录下,也是可以的。alias也有一些依赖是通过特殊的名称进行依赖,这时候就可以用alias别名来定义依赖关系即可dependencies: - name: subchart repository: http://localhost:10191 version: 0.1.0 alias: new-subchart-1templates模板文件遵循编写Go模板的标准约定,详情参阅:https://golang.org/pkg/text/template/变量模板文件中{{.Values.imageRegistry}}变量,这里的.values就是指明来在values.yaml文件。而imageRegistry和dockerTag才是第一个字段image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}而在values中的值,分别如下:imageRegistry: "quay.io/deis" dockerTag: "latest"也可以设置默认值预设值,如果.Values.storage存在就是用存在values值文件的值,如果不存在就是用默认default "minio",如下:value: {{default "minio" .Values.storage}}而以往使用的定义的配置清单,都可以引用模板语法格式,对一些可变动的属性值,可以做成变量引用,一些复杂的场景可以使用条件判断等,如:设置为ture或者false来启用或者关闭一段配置。此后,在安装的时候使用--values=VALUES.yaml即可预定义的值可以从模板中的对象访问通过values.yaml文件(或通过--set标志)提供的值.Values。也可以在模板中访问其他预定义的数据。以下值是预定义的,可用于每个模板,并且无法覆盖。与所有值一样,名称区分大小写。Release.Name:发布的名称(不是chart)Release.Time:chart发布上次更新的时间。这将匹配Last ReleasedRelease对象上的时间。Release.Namespace:chart发布到的名称空间。Release.Service:进行发布的服务。通常这是Tiller。Release.IsUpgrade:如果当前操作是升级或回滚,则设置为true。Release.IsInstall:如果当前操作是安装,则设置为true。Release.Revision:修订号。它从1开始,每个都递增helm upgrade。Chart:内容Chart.yaml。因此,chart版本可以Chart.Version和维护者一起获得Chart.Maintainers。Files:类似于地图的对象,包含chart中的所有非特殊文件。这不会授予您访问模板的权限,但可以访问存在的其他文件(除非使用它们除外.helmignore)。可以使用{{index .Files "file.name"}}或使用{{.Files.Get name}}或 {{.Files.GetString name}}函数访问文件。您也可以访问该文件的内容,[]byte使用{{.Files.GetBytes}}Capabilities:类似于地图的对象,包含有关Kubernetes({{.Capabilities.KubeVersion}},Tiller({{.Capabilities.TillerVersion}}和支持的Kubernetes API)版本({{.Capabilities.APIVersions.Has "batch/v1")的版本的信息注意:将删除任何未知的Chart.yaml字段。它们将无法在Chart对象内部访问。因此,Chart.yaml不能用于将任意结构化数据传递到模板中。但是,值文件可以用于此目的。如果要修改一个值就可以使用set修改。创建charthelm create创建一个linuxea.com的chartChart.yaml[root@linuxea helm]# helm create linuxea Creating linuxea而后生成如下清单而后修改一下Chart文件[root@linuxea linuxea]# cat Chart.yaml apiVersion: v1 appVersion: "1.0" description: A Helm chart for linuxea name: linuxea version: 0.1.0 maintainer: - name: mark email: linuxea@gmail.com依赖文件requirements,先不定义NOTES.txt这个文件是在安装生成chart之后,提示给用户的使用信息,也在helm status命令中显示_helpers.tpltpl模板语法用法ymldeployment.yaml ingress.yaml service.yaml在deployment.yaml中语法格式,有1级字段和二级字段,如下:[root@linuxea templates]# grep Values *.yaml deployment.yaml: replicas: {{ .Values.replicaCount }} deployment.yaml: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"并且还有一些复杂语法模式{{ toYaml .Values.resources | indent 12 }} {{- with .Values.nodeSelector }} nodeSelector: {{ toYaml . | indent 8 }} {{- end }} {{- with .Values.affinity }} affinity: {{ toYaml . | indent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{ toYaml . | indent 8 }} {{- end }}在service.yaml中可以赋值大多数的可变变量[root@linuxea templates]# cat service.yaml apiVersion: v1 kind: Service metadata: name: {{ include "linuxea.com.fullname" . }} labels: app.kubernetes.io/name: {{ include "linuxea.name" . }} helm.sh/chart: {{ include "linuxea.chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: app.kubernetes.io/name: {{ include "linuxea.name" . }} app.kubernetes.io/instance: {{ .Release.Name }}以及ingress.yaml[root@linuxea templates]# cat ingress.yaml {{- if .Values.ingress.enabled -}} {{- $fullName := include "linuxea.fullname" . -}} {{- $ingressPath := .Values.ingress.path -}} apiVersion: extensions/v1beta1 kind: Ingress metadata: name: {{ $fullName }} labels: app.kubernetes.io/name: {{ include "linuxea.name" . }} helm.sh/chart: {{ include "linuxea.chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- with .Values.ingress.annotations }} annotations: {{ toYaml . | indent 4 }} {{- end }} spec: {{- if .Values.ingress.tls }} tls: {{- range .Values.ingress.tls }} - hosts: {{- range .hosts }} - {{ . | quote }} {{- end }} secretName: {{ .secretName }} {{- end }} {{- end }} rules: {{- range .Values.ingress.hosts }} - host: {{ . | quote }} http: paths: - path: {{ $ingressPath }} backend: serviceName: {{ $fullName }} servicePort: http {{- end }} {{- end }}修改values参数简单修改几项replicaCount: 2打开resources,这里需要将{}删掉,如果启用了的话resources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Mi检查语法而后检查语法是否错误,在父级目录检查[root@linuxea helm]# helm lint linuxea ==> Linting linuxea [INFO] Chart.yaml: icon is recommended 1 chart(s) linted, no failures打包如果没有错误,就可以进行打包,如果有必要,也可以上传到仓库中[root@linuxea helm]# helm package linuxea/ Successfully packaged chart and saved it to: /root/linuxea/manifests/helm/linuxea-0.1.0.tgz[root@linuxea helm]# ll total 40 drwxr-xr-x. 4 root root 93 Nov 18 12:08 linuxea -rw-r--r--. 1 root root 2614 Nov 18 12:09 linuxea-0.1.0.tgz本地仓库我们打开本地的仓库,本地仓库需要运行才能正常使用[root@linuxea linuxea]# helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts 打开一个临时简单的仓库服务,也可以用nginx当作仓库服务使用[root@linuxea prometheus]# helm serve Regenerating index. This may take a moment. Now serving you on 127.0.0.1:8879[root@linuxea linuxea]# ss -tlnp|grep 8879 LISTEN 0 128 127.0.0.1:8879 *:* users:(("helm",pid=3816,fd=3))但是,helm仓库不允许使用命令行上传,但是当创建之后就会被记录下来,可通过helm search查看[root@linuxea helm]# helm search linuxea NAME CHART VERSION APP VERSION DESCRIPTION local/linuxea 0.1.0 1.0 A Helm chart for linuxea.com尤为注意的是NOTES.txt 文件需要真正反映安装相关配置参数,需要进行定义成具体相关的内容安装chart安装[root@linuxea ~]# helm install --name linuxe local/linuxea NAME: linuxe LAST DEPLOYED: Sun Nov 18 12:10:27 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME AGE linuxe-linuxea 1s ==> v1beta2/Deployment linuxe-linuxea 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE linuxe-linuxea-666bf7dc5b-476gm 0/1 Pending 0 1s linuxe-linuxea-666bf7dc5b-xgs8h 0/1 Pending 0 1s NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=linuxea,app.kubernetes.io/instance=linuxe" -o jsonpath="{.items[0].metadata.name}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl port-forward $POD_NAME 8080:80[root@linuxea ~]# kubectl get pods NAME READY STATUS RESTARTS AGE linuxe-linuxea-666bf7dc5b-476gm 1/1 Running 0 1m linuxe-linuxea-666bf7dc5b-xgs8h 1/1 Running 0 1m linuxea-redis-master-0 1/1 Running 0 6h linuxea-redis-slave-77f4768cd8-rf4l2 1/1 Running 1 6h这里安装的信息是存储在NOTES.txt ,可以在此获取[root@linuxea helm]# helm status linuxe LAST DEPLOYED: Sun Nov 18 12:10:27 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE linuxe-linuxea-666bf7dc5b-476gm 1/1 Running 0 3m linuxe-linuxea-666bf7dc5b-xgs8h 1/1 Running 0 3m ==> v1/Service NAME AGE linuxe-linuxea 3m ==> v1beta2/Deployment linuxe-linuxea 3m NOTES: 1. Get the application URL by running these commands: export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=linuxea,app.kubernetes.io/instance=linuxe" -o jsonpath="{.items[0].metadata.name}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl port-forward $POD_NAME 8080:80卸载chart--purge移除[root@linuxea helm]# helm del --purge linuxe2 release "linuxe2" deleted [root@linuxea helm]# helm del --purge linuxe21 Error: release: "linuxe21" not found [root@linuxea helm]# helm del --purge linuxe1 release "linuxe1" deleted [root@linuxea helm]# helm del --purge linuxe release "linuxe" deleted添加仓库添加incubator,incubator是不稳定的版本[root@linuxea helm]# helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/ "incubator" has been added to your repositories [root@linuxea helm]# helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts incubator https://kubernetes-charts-incubator.storage.googleapis.com/
2018年12月17日
3,151 阅读
0 评论
0 点赞
2018-12-16
linuxea:kubernetes helm简单使用(50)
核心组件与程序架构核心组件Chart一个helm程序包,包含了k8s上部署应用程序的清单的定义(并不包含镜像,镜像是由镜像仓库来提供),镜像的引用,依赖关系,资源定义等等。必要时,包含其他的定义,如:Service.Repository而Chart是有多个,放置到Repository,也可以说是一个Chart。同时也是一个http/https服务器。ReleaseChart实例化后部署在kubernetes cluster之上的Chart实例,就叫做Release。之所以称作为Release,是因为将Chart拿来提供了配置信息。在chart中,会提供一些配置信息,也就是值文件,这些文件最终用来给模板赋值,而后将Chart模板当中的属性使用config或者值文件赋值后生成Release。而config就是值文件,也是应用程序实例化安装运行时候使用的配置信息。程序架构而helm程序由两部分组成,helm客户端和tiller服务端。服务端可以运行在kubernetes之上,也可以运行在kubernetes集群之外,如果运行在kubernetes集群外配置起来是非常麻烦的,多数情况下tiller都会运行在kubernetes集群之上。而helm只是作为本地的客户端,helm基于go语言编写,基于GRPC协议与tiller server进行交互,能够实现管理本地的chart仓库,也可以管理chart,也要与tiller交互,用于发送chart,实现实例安装,查询,卸载等操作。 tiller作为服务端,监听来自helm的请求,而后将helm发来的chart和config合并在一起(将config赋值到chart当中),完成部署应用程序,生成release。helm安装helm是工作在本地的客户端,不必要是k8s集群内的主机来进行安装部署。[root@linuxea ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.11.0-linux-amd64.tar.gz[root@linuxea ~]# tar xf helm-v2.11.0-linux-amd64.tar.gz -C /usr/local/ [root@linuxea ~]# ln -s /usr/local/linux-amd64/helm /usr/local/bin/helm[root@linuxea ~]# helm version Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"} Error: could not find tiller [root@linuxea ~]# tiller生成tiller使用init本身就可以自动生成。helm本身第一次init的时候会联系到api server,api server只会着部署tiller的pod,这也就意味着helm需要链接api server,且需要认认证,并还要管理员权限。helm会获取当前系统的上的kuberctl的权限,在~/.kube/下的config文件是可以被helm获取到。helm会扮演成kubectl客户端,进行初始化和部署安装。[root@linuxea ~]# ls ~/.kube/ cache config http-cachetiller部署在K8s集群的时候,tiller需要获取集群的管理权限,以便于完成安装,卸载等的管理权限。.RBAC权限部署完成helm之后在进行部署tiller的时候,需要在k8s有RBAC集群上,设置RBAC的配置,依赖的用户名(service accout)就是叫做tiller。这个tiller如果要很大的权限的话,就需要绑定到clusterrobingd之上。如下:此前部署k8s集群的时候是强制启用RBAC的,那就需要配置RBAC[root@linuxea manifests]# cat ~/linuxea/manifests/tiller-rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system如果是名称空间就需要其他的配置。其他配置参考:https://github.com/helm/helm/blob/master/docs/rbac.md#example-service-account-with-cluster-admin-roleapply[root@linuxea manifests]# kubectl apply -f ~/linuxea/manifests/tiller-rbac.yaml serviceaccount/tiller created clusterrolebinding.rbac.authorization.k8s.io/tiller created[root@linuxea manifests]# kubectl get sa -n kube-system|grep tiller tiller 1 28s生成在第一次生成的时候会在家目录下生成一个/root/.helm 的目录,其中包含很多本地参考的文件。最后在kubernetes-charts.storage.googleapis.com获取一个stable repo[root@linuxea manifests]# helm init --service-account tiller Creating /root/.helm Creating /root/.helm/repository Creating /root/.helm/repository/cache Creating /root/.helm/repository/local Creating /root/.helm/plugins Creating /root/.helm/starters Creating /root/.helm/cache/archive Creating /root/.helm/repository/repositories.yaml Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com Adding local repo with URL: http://127.0.0.1:8879/charts $HELM_HOME has been configured at /root/.helm. Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster. Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy. To prevent this, run `helm init` with the --tiller-tls-verify flag. For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation Happy Helming! [root@linuxea [root@linuxea manifests]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-78fcdf6894-9q7cp 1/1 Running 0 2d coredns-78fcdf6894-t8vjc 1/1 Running 0 2d etcd-linuxea.master-1.com 1/1 Running 0 2d kube-apiserver-linuxea.master-1.com 1/1 Running 0 2d kube-controller-manager-linuxea.master-1.com 1/1 Running 0 2d kube-flannel-ds-amd64-j54qv 1/1 Running 0 2d kube-flannel-ds-amd64-kq995 1/1 Running 0 2d kube-flannel-ds-amd64-m2m6t 1/1 Running 0 2d kube-flannel-ds-amd64-sx5cz 1/1 Running 0 2d kube-flannel-ds-amd64-xfvst 1/1 Running 0 2d kube-proxy-8tvxw 1/1 Running 0 2d kube-proxy-9vr46 1/1 Running 0 2d kube-proxy-fmlfq 1/1 Running 0 2d kube-proxy-gt6sk 1/1 Running 0 2d kube-proxy-vtzm2 1/1 Running 0 2d kube-scheduler-linuxea.master-1.com 1/1 Running 0 2d metrics-server-v0.3.1-57ddf848d8-wdx6l 2/2 Running 0 2d tiller-deploy-57f988f854-g8hw6 1/1 Running 0 27s现在已经安装完成Client和Server端版本都是v2.11.0[root@linuxea ~]# helm version Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b146b", GitTreeState:"clean"}此刻可以安装一些应用程序,只需要install即可。由于tiller是由deploy控制器控制,如果要卸载 tiller服务端,只需要删除deploy控制器即可。使用helm远程更新仓库,helm repo update。这条命令会跳过本地而链接远程仓库。[root@linuxea ~]# helm repo update Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈ [root@linuxea ~]# 我们可以通过https://hub.kubeapps.com/查找一些helm资源。对一些资源选中就可以查看到详情页并且,也可以使用helm使用search搜索,这和docker类似。helm search --help查看帮助。如果没有填写关键词就会列出所有,helm search nginx搜索当前内所有的nginx可以用。如下:[root@linuxea ~]# helm search nginx NAME CHART VERSION APP VERSION DESCRIPTION stable/nginx-ingress 0.31.0 0.20.0 An nginx Ingress controller that uses ConfigMap to store ... stable/nginx-ldapauth-proxy 0.1.2 1.13.5 nginx proxy with ldapauth stable/nginx-lego 0.3.1 Chart for nginx-ingress-controller and kube-lego stable/gcloud-endpoints 0.1.2 1 DEPRECATED Develop, deploy, protect and monitor your APIs... [root@linuxea ~]# 并且可以探索内部的详细信息。这些信息和网页上说差不多[root@linuxea ~]# helm inspect stable/nginx-ingress其次,在repo list中可以看到有稳定版路径和本地路径,如果需要添加incubator,就需要将路径添加[root@linuxea ~]# helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts repo add 添加如下,参考:https://github.com/helm/charts[root@linuxea ~]# helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com/ "incubator" has been added to your repositories示例如果我们要安装一个应用,可以在搜索到后进行安装,并且配合values文件进行赋值。一般来讲,不赋值也会有默认参数。安装一个memcached为例[root@linuxea ~]# helm search memcached NAME CHART VERSION APP VERSION DESCRIPTION stable/memcached 2.3.1 1.5.6 Free & open source, high-performance, distributed memory ... stable/mcrouter 0.1.1 0.36.0 Mcrouter is a memcached protocol router for scaling memca...[root@linuxea ~]# helm inspect stable/memcached安装 helm install --name linuxea-men stable/memcached[root@linuxea ~]# helm install --name linuxea-men stable/memcached NAME: linuxea-men 名称 LAST DEPLOYED: Fri Nov 16 13:44:46 2018 部署时间 NAMESPACE: default 部署的名称空间 STATUS: DEPLOYED 当前状态 RESOURCES: ==> v1/Service NAME AGE linuxea-men-memcached 1s ==> v1beta1/StatefulSet linuxea-men-memcached 1s ==> v1beta1/PodDisruptionBudget pod回收机制 linuxea-men-memcached 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE linuxea-men-memcached-0 0/1 Pending 0 1s NOTES: Memcached can be accessed via port 11211 on the following DNS name from within your cluster: linuxea-men-memcached.default.svc.cluster.local If you'd like to test your instance, forward the port locally: export POD_NAME=$(kubectl get pods --namespace default -l "app=linuxea-men-memcached" -o jsonpath="{.items[0].metadata.name}") kubectl port-forward $POD_NAME 11211 In another tab, attempt to set a key: $ echo -e 'set mykey 0 60 5\r\nhello\r' | nc localhost 11211 You should see: STORED 并且可以使用 export POD_NAME=$(kubectl get pods --namespace default -l "app=linuxea-men-memcached" -o jsonpath="{.items[0].metadata.name}")验证删除使用[root@linuxea ~]# helm delete linuxea-menhelm常用命令: delete 删除 history 历史命令 install 安装 list 查看 rollback 回滚 search 查找 upgrade 修改 history 查看部署历史 status 获取状态信息chary管理命令create 创建 delete 删除 fetch 获取,从仓库下载到本地,并且展开 get 获取,仅仅下载 inspect 查看chart详细信息,包括使用,接收值,传递参数等等。 package 将本地开发的包打包 verify 校验示例2我们试图创建一个redis[root@linuxea ~]# helm search redis NAME CHART VERSION APP VERSION DESCRIPTION stable/prometheus-redis-exporter 0.3.4 0.21.2 Prometheus exporter for Redis metrics stable/redis 4.2.10 4.0.11 Open source, advanced key-value store. It is often referr... stable/redis-ha 3.0.1 4.0.11 Highly available Kubernetes implementation of Redis stable/sensu 0.2.3 0.28 Sensu monitoring framework backed by the Redis transport 安装[root@linuxea ~]# helm install --name redis1 stable/redis创建完成可以使用helm list进行查看[root@linuxea ~]# helm list NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE redis1 1 Sat Nov 17 06:30:50 2018 DEPLOYED redis-4.2.10 4.0.11 default right-molly 1 Fri Nov 16 13:50:01 2018 DEPLOYED nginx-ingress-0.31.0 0.20.0 default 所有安装的应用都会被get到本地来进行 应用,存放/root/.helm/cache/archive路径下[root@linuxea archive]# cd /root/.helm/cache/archive [root@linuxea archive]# ls memcached-2.3.1.tgz nginx-ingress-0.31.0.tgz redis-4.2.10.tgz这些taz包可以拆开[root@linuxea archive]# tar xf redis-4.2.10.tgz tar: redis/Chart.yaml: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/values.yaml: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/templates/NOTES.txt: implausibly old time stamp 1970-01-01 01:00:00 tar: redis/templates/_helpers.tpl: implausibly old time stamp 1970-01-01 01:00:00 ...其中这些Yaml文件与我们之前所写的大不一样[root@linuxea archive]# tree redis redis ├── Chart.yaml 描述信息 ├── README.md 叙述文件 ├── templates 模板文件 │ ├── configmap.yaml │ ├── health-configmap.yaml │ ├── _helpers.tpl │ ├── metrics-deployment.yaml │ ├── metrics-svc.yaml │ ├── networkpolicy.yaml │ ├── NOTES.txt │ ├── redis-master-statefulset.yaml │ ├── redis-master-svc.yaml │ ├── redis-rolebinding.yaml │ ├── redis-role.yaml │ ├── redis-serviceaccount.yaml │ ├── redis-slave-deployment.yaml │ ├── redis-slave-svc.yaml │ └── secret.yaml ├── values-production.yaml └── values.yaml 1 directory, 19 files [root@linuxea archive]# 这些yaml文件大多调用go模板语法进行赋不同的值传递参数来完成不同的部署,而之前所说的config就是为模板中的属性提供值的配置信息,也可以定义在values.yaml中,并且在install 的时候进行加载即可。其中双##号上注释,单#号表示可以启用的选项示例values我们修改values的一些配置信息,使得redis正常启动[root@linuxea archive]# cp redis/values.yaml ~/linuxea/manifests/helm/ [root@linuxea archive]# cd ~/linuxea/manifests/helm/我们修改下参数,使得使用本地目录存储 persistence: enabled: false删掉此前的创建的redis,在进行部署一次[root@linuxea templates]# helm delete right-molly redis1 release "right-molly" deleted release "redis1" deleted重新部署一次[root@linuxea helm]# helm install --name linuxea-redis -f values.yaml stable/redis[root@linuxea helm]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE linuxea-redis-master-0 1/1 Running 0 1m 172.16.4.64 linuxea.node-3.com linuxea-redis-slave-77f4768cd8-rf4l2 1/1 Running 1 1m 172.16.3.78 linuxea.node-2.com使用helm status linuxea-redis可以查看历史中的创建状态信息[root@linuxea helm]# helm status linuxea-redis LAST DEPLOYED: Sun Nov 18 05:16:38 2018 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1beta2/StatefulSet NAME AGE linuxea-redis-master 2m ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE linuxea-redis-slave-77f4768cd8-rf4l2 1/1 Running 1 2m linuxea-redis-master-0 1/1 Running 0 2m ==> v1/Secret NAME AGE linuxea-redis 2m ==> v1/ConfigMap linuxea-redis-health 2m ==> v1/Service linuxea-redis-master 2m linuxea-redis-slave 2m ==> v1beta1/Deployment linuxea-redis-slave 2m NOTES: ** Please be patient while the chart is being deployed ** Redis can be accessed via port 6379 on the following DNS names from within your cluster: linuxea-redis-master.default.svc.cluster.local for read/write operations linuxea-redis-slave.default.svc.cluster.local for read-only operations To get your password run: export REDIS_PASSWORD=$(kubectl get secret --namespace default linuxea-redis -o jsonpath="{.data.redis-password}" | base64 --decode) To connect to your Redis server: 1. Run a Redis pod that you can use as a client: kubectl run --namespace default linuxea-redis-client --rm --tty -i \ --env REDIS_PASSWORD=$REDIS_PASSWORD \ --image docker.io/bitnami/redis:4.0.11 -- bash 2. Connect using the Redis CLI: redis-cli -h linuxea-redis-master -a $REDIS_PASSWORD redis-cli -h linuxea-redis-slave -a $REDIS_PASSWORD To connect to your database from outside the cluster execute the following commands: kubectl port-forward --namespace default svc/linuxea-redis 6379:6379 & redis-cli -h 127.0.0.1 -p 6379 -a $REDIS_PASSWORD我们run一个client试图登录[root@linuxea helm]# kubectl run --namespace default linuxea-redis-client --rm --tty -i \ > --env REDIS_PASSWORD=$REDIS_PASSWORD \ > --image docker.io/bitnami/redis:4.0.11 -- bash If you don't see a command prompt, try pressing enter. I have no name!@linuxea-redis-client-79859b8d88-2zczc:/$ 而后直接登录redisI have no name!@linuxea-redis-client-79859b8d88-2zczc:/$ redis-cli -h linuxea-redis-master -a $REDIS_PASSWORD Warning: Using a password with '-a' option on the command line interface may not be safe.可info查看linuxea-redis-master:6379> info # Server redis_version:4.0.11 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:a3b8846cf74959a5 redis_mode:standalone os:Linux 4.9.12-1.el7.centos.x86_64 x86_64 arch_bits:64 multiplexing_api:epoll atomicvar_api:atomic-builtin gcc_version:6.3.0 process_id:1 run_id:d4288c1f28433ba066538fb02d33bcb0038a9f97 tcp_port:6379 uptime_in_seconds:246 uptime_in_days:0 hz:10 lru_clock:15791815 executable:/opt/bitnami/redis/bin/redis-server config_file:/opt/bitnami/redis/etc/redis.conf # Clients connected_clients:1 client_longest_output_list:0 client_biggest_input_buf:0 blocked_clients:0 # Memory used_memory:1917896 used_memory_human:1.83M used_memory_rss:11833344 used_memory_rss_human:11.29M查看主从状态# Replication role:master connected_slaves:1 slave0:ip=172.16.3.78,port=6379,state=online,offset=322,lag=1 master_replid:6f6a4fe934510bc0187e62c519fc28ee53cf0d8d master_replid2:0000000000000000000000000000000000000000 master_repl_offset:322 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:322 # CPU used_cpu_sys:0.11 used_cpu_user:0.12 used_cpu_sys_children:0.04 used_cpu_user_children:0.02 # Cluster cluster_enabled:0 # Keyspace linuxea-redis-master:6379>
2018年12月16日
3,271 阅读
0 评论
0 点赞
2018-12-14
linuxea:kubernetes helm概述(49)
此前,不管是无状态还是有状态的应用在部署在系统之上,如果是无状态的,使用Deployment控制器进行应用伸缩是很容易。有状态的应用也可以做一些限制不进行规模的伸缩,并且也可以完成持久存储能力的。但是一旦将有状态的应用扩展成多个副本,就会面临问题,不同的应用程序在扩展的时候,扩展的方式是各自都不相同的。如:redis主从,以及cluster都是不同的方式,etcd也是如此,这样的有状态应用部署在集群之上是一件不容易的事情。kubernetes在配置一个应用程序的时候,是很麻烦的。首先,需要写一个很长的配置清单,从而去安装应用程序。在此前的管理方式里面,有直接使用命令创建,也有命令式配置文件和声明式配置文件。声明式配置文件借助本地的配置文件,也能够在很大程度上减轻前期的开发使用。我们知道在linux系统之上,最初的时候也面临过这样的问题,程序包的维护代价非常大,安装一个应用程序的是时候就需要编译,而编译本身就比较复杂,且难以适配。如:版本问题等。后来就开发了包管理器RPM,但是RPM包单单解决了编译的问题,依赖包仍然匹配仍然让人头疼。后来又开发了如yum,apt这类解决依赖关系的工具。有了yum之后,对于安装程序来讲,基本上一键安装。同样,kubernetes在应用安装上,使用Helm也是可以的。helmhelm是kubernentes的另外一个项目,专为kubernetes上的应用程序而开发。heml的工作方式和yum和相似,首先是有一台仓库服务器,其中定义了配置,部署k8s的应用程序的清单文件。这一点和yum不一样的,yum本身不但解决依赖关系,也要提供应用程序包。但是在k8s中heml是不提供程序包的,而单单提供清单。而镜像由镜像仓库或者dockerhub和私有仓库等。如一个应用在部署的时候所需要的所有清单文件。这个程序包只提供清单,不包含镜像。如:nginx部署,对于nginx部署来将,首先需要nginx镜像,Deployment,还有service,如果有必要还有hpa的定义。将这三个文件打包在一起,就叫做一个应用程序包,在heml中称这个应用程序包为Chart。不同的用户在部署Chart时也不尽相同,配置文件,证书都不尽相同。通常以模板的形式通过配置环境变量传递一些自定义的设定,也就意味着并不能够简单的一条命令安装完成,尤其是在做一些定制化配置时。模板本身是不能进行修改,可通过赋值的方式修改,因此就会有一个值文件,用于模板引用给属性赋值,从而使得让用户能自定义安装。很多属性都是有默认值的,不赋值任何信息也可以基本的运行起来。类似于这样的Chart有很多个,这样的Chart仓库在互联网上可以使用helm提供的官网仓库。当然,也允许用户自定义上传chart,和github,dockerhub类似。要想成功部署chart应用,就需要k8s集群,而在k8s中,最终将期望请求操作落地的是api server,提交给api server是需要验证部署请求操作的。而helm是工作在k8s集群之外的,类似与Kubectl 客户端的形式。但是helm不直接于api server交互。我们假设有一台笔记本用于kubernetes通讯,便于管理操作kubernetes,在这台机器上安装一个Helm,helm也是一个命令行客户端工具。当需要通过helm在k8s集群上部署应用程序时候,不直接操作api server,而是由一个中间件Tiller操作,并且tiller是一个服务端,而helm host是客户端。Tiller是一个守护进程,监听在某个端口上,接收Helm的请求,Tiller可以运行在helm主机之上。但更好的方式是将Tiller运行在kubernetes集群之上(服务类的应用托管在k8s集群之上较为妥当)。tiller是于Helm之间完成的交互。helm host是tiller的客户端,每一次部署应用发起请求的时候,helm提交请求给tiller,tiller再去链接api server,再由api server完成创建。这样一来,对于api server来讲,客户端程序不是helm ,而是tiller。在helm之上,和docker的管理方式很相似,每一个chart在使用的时候一般都要从Helm仓库中下载到本地的helm主机上的运行helm用户的家目录下存放这个chart。当安装一个的应用的时候就会去helm下载存储在本地一个。也可以在本地开发,本地使用。这和很多场景下的情况相似,在helm仓库下载之前会在本地查看,如果本地有就使用,本地有和远程是否有是没有关系的。如果本地没有才会去远程下载存放本地。而当试图去部署应用程序的时候,helm先联系Tiller,由Tiller联系api server来完成部署和应用。helm可以将一个chart在kubernetes cluster上部署多份副本,对应名称或者名称空间各不相同。而部署到kubernetes 之后就不在叫做Chart了,Chart仅当作定义,我们需要把给定的值赋值到模板中以后,生成很多信息就有了的实例,通常我们称为对象。由此,Chart更像是某一种部署的类型的。这种类被赋值后就成为一个对象,不过他在kubernetes中不称为对象,而称为release。一旦被部署就不在叫做Chart,而是release。而同一个Chart给赋予不同的属性值后,完全可以部署出多个release来的。这便是helm的工作逻辑和架构形式。helm从仓库拉下来赋值之后提交给Tiller,由Tiller认证到api server完成在本地对应资源的管理,每一个资源管理的对象叫做release。helm将kuernetes资源打包到一个Chart当中,制作并测试完成各个Chart和Chart本身的依赖关系,并利用Chart参考对外实现分发,而helm可以通过vlues文件完成可配置的发布,同时支持配置程序的版本管理,而且还能简化kubernetes部署的版本控制,打包,发布,删除,更新操作。也就是说,如果Chart版本更新了,helm自动支持滚动更新机制,并且可以一键回滚。
2018年12月14日
2,402 阅读
0 评论
0 点赞
2018-12-12
linuxea:kubernetes hpa(Horizontal Pod Autoscaler)示例(48)
hpahpa有着非常强大的功能,支持应用规模的自动伸缩。如果某一个pod,资源利用率达到一个临界值后,会自动的修改Deployment的replicas值,这种方式也有自动计算结果得到的。比如说,我有5个pod,我期望每个负载率是90% 就进行扩展一个pod,依次类推。当负载降下来的时候就在自动所容到正常的个数。hpa是有两个版本,v1使用核心指标定义,而核心指标中只有cpu和内存,而内存不可压缩资源,也不支持弹性压缩,那就只能使用cpu指标进行伸缩[root@linuxea linuxea]# kubectl api-versions autoscaling/v1 autoscaling/v2beta1在explain hpa.spec中:maxReplicas:最大副本数minReplicas:最少副本数targetCPUUtilizationPercentage:cpu评估,cpu利用率到多少就开始伸缩在hpa.spec.scaleTargetRef: 基于资源伸缩标准资源自动伸缩我们创建一个pod,并且做资源限制.yaml如下:[root@linuxea linuxea]# cat deploy-hpa.yaml apiVersion: apps/v1 kind: Deployment metadata: name: linuxea-hpa namespace: default labels: www: linuxea-com tier: backend spec: replicas: 1 selector: matchLabels: version: v0.1.32 template: metadata: labels: version: v0.1.32 spec: containers: - name: nginx-hpa image: marksugar/nginx:1.14.b ports: - name: http containerPort: 80 resources: requests: cpu: "300m" memory: "256Mi" limits: cpu: "1" memory: "512Mi"[root@linuxea linuxea]# kubectl apply -f deploy-hpa.yaml deployment.apps/linuxea-hpa created[root@linuxea linuxea]# kubectl get pods NAME READY STATUS RESTARTS AGE linuxea-hpa-6f7b8ddb67-cfcdw 1/1 Running 0 5s而后配置service[root@linuxea linuxea]# cat deploy-hpa-svc.yaml kind: Service apiVersion: v1 metadata: name: linuxea-hpa spec: type: NodePort ports: - port: 80 targetPort: 80 nodePort: 30080 selector: version: v0.1.32[root@linuxea linuxea]# kubectl apply -f deploy-hpa-svc.yaml service/linuxea-hpa created [root@linuxea linuxea]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17h linuxea-hpa NodePort 10.105.186.30 <none> 80:30080/TCP 6s这样一来就可以通过30080访问autoscaleautoscale我们定义自动伸缩,创建一个autoscale的控制器。kubectl autoscale --help指明最多有几个,最少有几个,cpu利用率最多不能超过多少 # Auto scale a deployment "foo", with the number of pods between 2 and 10, no target CPU utilization specified so a default autoscaling policy will be used: kubectl autoscale deployment foo --min=2 --max=10 # Auto scale a replication controller "foo", with the number of pods between 1 and 5, target CPU utilization at 80%: kubectl autoscale rc foo --max=5 --cpu-percent=80使用autoscale定义,最少一个,最多八个,cpu利用率最多不能使用超过60[root@linuxea linuxea]# kubectl autoscale deployment linuxea-hpa --min=1 --max=8 --cpu-percent=60 horizontalpodautoscaler.autoscaling/linuxea-hpa autoscaled像这样[root@linuxea linuxea]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE linuxea-hpa Deployment/linuxea-hpa <unknown>/60% 1 8 0 4s[root@linuxea linuxea]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE linuxea-hpa Deployment/linuxea-hpa 0%/60% 1 8 1 7s我们做一些压力测试,如果CPU到60%就会创建新的pod压力测试[root@linuxea linuxea]# ab -c 1000 -n 150099 http://10.10.240.161:30080/linuxea.html[root@linuxea linuxea]# kubectl describe hpa Name: linuxea-hpa Namespace: default Labels: <none> Annotations: <none> CreationTimestamp: Sun, 11 Nov 2018 07:29:54 +0000 Reference: Deployment/linuxea-hpa Metrics: ( current / target ) resource cpu on pods (as a percentage of request): 105% (316m) / 60% Min replicas: 1 Max replicas: 8 Deployment pods: 1 current / 2 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale True SucceededRescale the HPA controller was able to update the target scale to 2 ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited False DesiredWithinRange the desired count is within the acceptable range Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 6s horizontal-pod-autoscaler New size: 2; reason: cpu resource utilization (percentage of request) above target 随着负载的上涨,pod也会创建[root@linuxea linuxea]# kubectl get pods NAME READY STATUS RESTARTS AGE linuxea-hpa-6f7b8ddb67-hrb64 1/1 Running 0 10m linuxea-hpa-6f7b8ddb67-mgnkc 1/1 Running 0 18s那么现在已经运行了两个[root@linuxea linuxea]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE linuxea-hpa Deployment/linuxea-hpa 0%/60% 1 8 2 11m一旦负载超过阈值就会创建预设的最大值和最小值[root@linuxea linuxea]# kubectl get hpa -w NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE linuxea-hpa Deployment/linuxea-hpa 0%/60% 1 8 2 12m linuxea-hpa Deployment/linuxea-hpa 23%/60% 1 8 2 12m linuxea-hpa Deployment/linuxea-hpa 0%/60% 1 8 2 13m linuxea-hpa Deployment/linuxea-hpa 0%/60% 1 8 2 13m linuxea-hpa Deployment/linuxea-hpa 122%/60% 1 8 2 14m linuxea-hpa Deployment/linuxea-hpa 144%/60% 1 8 4 14m[root@linuxea linuxea]# kubectl get pods -w NAME READY STATUS RESTARTS AGE linuxea-hpa-6f7b8ddb67-hrb64 1/1 Running 0 11m linuxea-hpa-6f7b8ddb67-mgnkc 1/1 Running 0 1m linuxea-hpa-6f7b8ddb67-7bn99 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-7fl4c 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-7bn99 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-7fl4c 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-7bn99 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-7fl4c 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-7bn99 1/1 Running 0 1s linuxea-hpa-6f7b8ddb67-7fl4c 1/1 Running 0 1s[root@linuxea ~]# kubectl describe hpa Name: linuxea-hpa Namespace: default Labels: <none> Annotations: <none> CreationTimestamp: Sun, 11 Nov 2018 07:29:54 +0000 Reference: Deployment/linuxea-hpa Metrics: ( current / target ) resource cpu on pods (as a percentage of request): 144% (433m) / 60% Min replicas: 1 Max replicas: 8 Deployment pods: 4 current / 4 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale False BackoffBoth the time since the previous scale is still within both the downscale and upscale forbidden windows ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited False DesiredWithinRange the desired count is within the acceptable range Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 4m horizontal-pod-autoscaler New size: 2; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 37s horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target默认使用的autocale的v1控制器autoscaling/v2beta1使用autoscaling/v2beta1,kind为HorizontalPodAutoscaler。对linuxea-hpa进行扩展,如下spec: scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: linuxea-hpa对这个资源minReplicas最少一个,maxReplicas最大5个,metrics对cpu资源进行评估,当cpu使用30%就进行自动扩展,内存超过50M(targetAverageValue只能是值) minReplicas: 1 maxReplicas: 5 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 30 - type: Resource resource: name: memory targetAverageValue: 50Mi如下:[root@linuxea ~]# cat autoscale-hpa.yaml apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: linuxea-hpa-2 spec: scaleTargetRef: apiVersion: extensions/v1beta1 kind: Deployment name: linuxea-hpa minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 30 - type: Resource resource: name: memory targetAverageValue: 50Mi删掉v1版本的,而后apply v2beta1[root@linuxea ~]# kubectl delete hpa linuxea-hpa horizontalpodautoscaler.autoscaling "linuxea-hpa" deleted[root@linuxea ~]# kubectl apply -f autoscale-hpa.yaml horizontalpodautoscaler.autoscaling/linuxea-hpa-2 configured此时就可以对CPU和内存资源做评估[root@linuxea ~]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE linuxea-hpa-2 Deployment/linuxea-hpa <unknown>/50Mi, <unknown>/30% 1 10 5 3s如果压力满足就扩展,否则就缩减压测[root@linuxea linuxea]# ab -c 1000 -n 150099 http://10.10.240.161:30080/linuxea.html[root@linuxea ~]# kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE linuxea-hpa-2 Deployment/linuxea-hpa 107837030400m/50Mi, 0%/30% 1 10 5 6m当检测到压测,进行扩展[root@linuxea linuxea]# kubectl get pods -w NAME READY STATUS RESTARTS AGE linuxea-hpa-6f7b8ddb67-7bn99 1/1 Running 0 3m linuxea-hpa-6f7b8ddb67-7fl4c 1/1 Running 0 3m linuxea-hpa-6f7b8ddb67-c8ssz 1/1 Running 0 39s linuxea-hpa-6f7b8ddb67-hrb64 1/1 Running 0 18m linuxea-hpa-6f7b8ddb67-mgnkc 1/1 Running 0 7m linuxea-hpa-6f7b8ddb67-l89sk 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-vfkqj 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-l89sk 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-f96n5 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-vfkqj 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-gpxkt 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-f96n5 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-5kwtl 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-gpxkt 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-5kwtl 0/1 Pending 0 0s linuxea-hpa-6f7b8ddb67-vfkqj 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-l89sk 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-f96n5 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-5kwtl 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-gpxkt 0/1 ContainerCreating 0 0s linuxea-hpa-6f7b8ddb67-l89sk 1/1 Running 0 1s linuxea-hpa-6f7b8ddb67-gpxkt 1/1 Running 0 1s linuxea-hpa-6f7b8ddb67-5kwtl 1/1 Running 0 2s linuxea-hpa-6f7b8ddb67-f96n5 1/1 Running 0 2s linuxea-hpa-6f7b8ddb67-vfkqj 1/1 Running 0 2s可使用kubectl describe hpa 查看[root@linuxea ~]# kubectl describe hpa Name: linuxea-hpa-2 Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"autoscaling/v2beta1","kind":"HorizontalPodAutoscaler","metadata":{"annotations":{},"name":"linuxea-hpa-2","namespace":"default"},"spec":... CreationTimestamp: Sun, 11 Nov 2018 07:46:29 +0000 Reference: Deployment/linuxea-hpa Metrics: ( current / target ) resource memory on pods: 107750195200m / 50Mi resource cpu on pods (as a percentage of request): 73% (221m) / 30% Min replicas: 1 Max replicas: 5 Deployment pods: 5 current / 5 desired Conditions: Type Status Reason Message ---- ------ ------ ------- AbleToScale False BackoffBoth the time since the previous scale is still within both the downscale and upscale forbidden windows ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request) ScalingLimited True TooManyReplicas the desired replica count is more than the maximum replica count Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 2m horizontal-pod-autoscaler New size: 5; reason: memory resource above target缩减的速度非常的慢,需要等待。如果能够通过prometheus导出指标,就可以根据指标来做伸缩。每个pod上做的资源指标可以用否,取决于prometheus能够从 pod内的应用获取到什么指标的。在开发这些应用的时候就应该输出指标数据,当前能够承载的最大访问数,可以基于此类的方式,特定的指标做扩展。不过,这些需要进行自己去定义,并且支持。自定义指标type为pods,说明使用pods中的名称为http_requests的指标,达到300个就扩展 metrics: - type: Pods name: metricsName: http_requests targetAverageValue: 300m其他参考
2018年12月12日
2,658 阅读
0 评论
0 点赞
2018-12-11
linuxea:kubernetes 部署prometheus和grafana(47)
prometheusmetrics-server可以对核心指标进行监控。 除开节点,podCPU内存之外的其他指标是无法获取的,就要借助prometheus。prometheus提供的资源指标是不能够被k8s解析的,要想能在k8s上使用prometheus, 就需要额外加一个prometheus的资源转换,转成k8s api能够兼容的格式,才能被当作指标数据使用。架构形式如下:prometheus本身就是一个监控系统,有一个代理插件,如zabbix和zabbix-agent。我们先假设prometheus是server端。prometheus要从一个被监控主机节点来获取数据,如果这个节点不是一个pod,而是一个虚拟机,物理机,就部署一个专门的软件 -> node_exoorter,而node_exoorter就相当于客户端。node_exoorter能够让prometheus来采集指标数据的组件,但是这个组件只是用来去暴露,输出,采集当前节点的节点级别的数据。如果要采集其他的,比如haproxy,就需要haproxy的exoorter。如果要去采集pod,pod也有专门的exoorter接口。而且,容器的日志也在节点之上的/var/log/containers/中,这些日志从接口被输出来。事实上只需要获取到节点上的这些日志,就能够很容易的获取节点上pod容器中的日志。简单的说prometheus就是通过metrics rul到各个pod获取数据,这些数据被采集后通过一个PromQL查询语句进行查询,PromQL支持restfull风格接口的查询条件表达式。通过这种restfull接口方式可以监控到采集到各种指标数据,但是这些指标不能够被k8s的api server所解释,因为这两种是不互相兼容的。如果期望通过k8s的api server像在api中请求获取数据一样获取指标数据,并且是prometheus采集的指标数据,就必须把PromQL的数据转换成k8s中自定义定义的的查询接口格式(costom metics API),就需要在k8s的(costom metics AP)接口下嵌套一个组件,这个组件称为k8s-promethues-adpater,是有第三方提供。而kube-state-metrics 负责转换数据,k8s-promethues-adpater负责接收转换的数据。如下:PromQL语句完成从Prometheus查询到语句,并转为k8s api上的指标格式数据,并支持通过api获取。前提是将custom Metrics API聚合到api server,就能正常从api-versions看到这个api。promethues是有状态应用,并且自身就是一个时间序列数据库prometheus-configmap.yaml 统计pod数据和定义运行环境的 kube-state-metrics-deployment.yaml 部署k8s-prometheus-adpater,使自定义的指标数据被系统使用 alertmanager-pvc.yaml 警报器管理器,使用到pvc prometheus-statefulset.yaml 配置需求 kube-state-metrics-deployment.yaml 这些是将prometheus数据转换 kube-state-metrics-rbac.yaml kube-state-metrics-service.yaml 要聚合成api server中的功能 ,就需要在部署一个组件,k8s-prometheus-adpaterpromethues是有状态应用,因此,使用statefulset控制。如果一个pod server不够就需要多个,这也就是使用statefulset的原因。使用https://github.com/iKubernetes/k8s-prom路径下的文件进行,完成部署实验创建一个prom的名称空间,运行prometheusk8s-prometheus-adapter 完成自定义数据应用 kube-state-metrics # kube-state部署相关 namespace.yaml 创建prom名称空间 node_exporter 收集节点指标 prometheus 使用deploy部署prometheus克隆[root@linuxea opt]# git clone https://github.com/iKubernetes/k8s-prom.git Cloning into 'k8s-prom'... remote: Enumerating objects: 46, done. remote: Total 46 (delta 0), reused 0 (delta 0), pack-reused 46 Unpacking objects: 100% (46/46), done. [root@linuxea opt]# tree k8s-prom/ -bash: tree: command not found [root@linuxea opt]# cd k8s-prom/创建名称空间[root@linuxea k8s-prom]# kubectl apply -f namespace.yaml namespace/prom created部署node_exporterapply node_exporter[root@linuxea k8s-prom]# kubectl apply -f node_exporter/ daemonset.apps/prometheus-node-exporter created service/prometheus-node-exporter created而后在prom中的名称空间下的pod已经运行起来,这些pod的kind是DaemonSet,每个节点会运行一个pod,收集Node主机资源。包括主节点这里面的node-exporter pod版本用的是prom/node-exporter:v0.16.0[root@linuxea k8s-prom]# kubectl get pods,svc -n prom NAME READY STATUS RESTARTS AGE IP prometheus-node-exporter-b7f2s 1/1 Running 0 2m4s 10.10.240.161 prometheus-node-exporter-cqnwh 1/1 Running 0 2m4s 10.10.240.142 prometheus-node-exporter-k2q7f 1/1 Running 0 2m4s 10.10.240.203 prometheus-node-exporter-x86b4 1/1 Running 0 2m4s 10.10.240.202 prometheus-node-exporter-znhb8 1/1 Running 0 2m4s 10.10.240.143 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/prometheus-node-exporter ClusterIP None <none> 9100/TCP 2m31s部署prometheus创建prometheus[root@linuxea k8s-prom]# kubectl apply -f prometheus/ configmap/prometheus-config created deployment.apps/prometheus-server created clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created service/prometheus createdprometheus是以30090端口暴露出来的[root@linuxea k8s-prom]# kubectl get pods,svc -n prom NAME READY STATUS RESTARTS AGE pod/prometheus-node-exporter-4xq5h 1/1 Running 0 37m pod/prometheus-node-exporter-8qh82 1/1 Running 0 37m pod/prometheus-node-exporter-b5kwx 1/1 Running 0 37m pod/prometheus-node-exporter-dgvfv 1/1 Running 0 37m pod/prometheus-node-exporter-gm9pv 1/1 Running 0 37m pod/prometheus-server-5f8cd4755-ns5l7 1/1 Running 0 11m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/prometheus NodePort 10.105.244.208 <none> 9090:30090/TCP 11m service/prometheus-node-exporter ClusterIP None <none> 9100/TCP 37m而后使用30090访问部署kube-state-metrics部署使用kube-state-metrics[root@linuxea k8s-prom]# kubectl apply -f kube-state-metrics/ deployment.apps/kube-state-metrics created serviceaccount/kube-state-metrics created clusterrole.rbac.authorization.k8s.io/kube-state-metrics created clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created service/kube-state-metrics createdkube-state-metrics输出的service监听在8080端口之上,向外提供服务的。[root@linuxea k8s-prom]# kubectl get all -n prom NAME READY STATUS RESTARTS AGE pod/kube-state-metrics-68d7c699c6-gstgg 1/1 Running 0 9m34s pod/prometheus-node-exporter-4xq5h 1/1 Running 0 84m pod/prometheus-node-exporter-8qh82 1/1 Running 0 84m pod/prometheus-node-exporter-b5kwx 1/1 Running 0 84m pod/prometheus-node-exporter-dgvfv 1/1 Running 0 84m pod/prometheus-node-exporter-gm9pv 1/1 Running 0 84m pod/prometheus-server-5f8cd4755-ns5l7 1/1 Running 0 59m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-state-metrics ClusterIP 10.98.44.126 <none> 8080/TCP 9m35s service/prometheus NodePort 10.105.244.208 <none> 9090:30090/TCP 59m service/prometheus-node-exporter ClusterIP None <none> 9100/TCP 84m NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/prometheus-node-exporter 5 5 5 5 5 <none> 84m NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/kube-state-metrics 1 1 1 1 9m35s deployment.apps/prometheus-server 1 1 1 1 59m NAME DESIRED CURRENT READY AGE replicaset.apps/kube-state-metrics-68d7c699c6 1 1 1 9m35s replicaset.apps/prometheus-server-5f8cd4755 1 1 1 59m部署prometheus-adapterk8s-prometheus-adapter需要给予https提供服务,而默认情况下k8s-prometheus-adapter是http协议的。需要提供一个证书,使其运行成https,并且需要被此k8s服务器认可的ca签署才可以。我们自制一个即可。而后创建secret,名称和custom-metrics-apiserver-deployment.yaml 中一样 secret: secretName: cm-adapter-serving-certs自制证书[root@linuxea ~]# cd /etc/kubernetes/pki生成私钥[root@linuxea pki]# (umask 077;openssl genrsa -out serving.key 2048) Generating RSA private key, 2048 bit long modulus ..............+++ ...............................+++ e is 65537 (0x10001)生成签署请求[root@linuxea pki]# openssl req -new -key serving.key -out serving.csr -subj "/CN=serving" [root@linuxea pki]# ll serving.* -rw-r--r--. 1 root root 887 Nov 10 09:38 serving.csr -rw-------. 1 root root 1675 Nov 10 09:36 serving.key签证[root@linuxea pki]# openssl x509 -req -in serving.csr -CA ./ca.crt -CAkey ./ca.key -CAcreateserial -out serving.crt -days 3650 Signature ok subject=/CN=serving Getting CA Private Key [root@linuxea pki]# ll serving.* -rw-r--r--. 1 root root 977 Nov 10 09:39 serving.crt -rw-r--r--. 1 root root 887 Nov 10 09:38 serving.csr -rw-------. 1 root root 1675 Nov 10 09:36 serving.key创建secret在prom名称空间中创建secret[root@linuxea pki]# kubectl create secret generic cm-adapter-serving-certs --from-file=serving.crt=./serving.crt --from-file=serving.key=./serving.key -n prom secret/cm-adapter-serving-certs created[root@linuxea pki]# kubectl get secret -n prom NAME TYPE DATA AGE cm-adapter-serving-certs Opaque 2 4s default-token-x8t89 kubernetes.io/service-account-token 3 144m kube-state-metrics-token-6n8rj kubernetes.io/service-account-token 3 26m prometheus-token-8lqgk kubernetes.io/service-account-token 3 76mprometheus-adapter在应用之前,我们修改几个参数先替换到custom-metrics-apiserver-deployment.yaml文件[root@linuxea k8s-prom]# mv /opt/k8s-prom/k8s-prometheus-adapter/custom-metrics-apiserver-deployment.yaml /opt/下载k8s-prometheus-adapter[root@linuxea k8s-prom]# curl -Lks https://raw.githubusercontent.com/DirectXMan12/k8s-prometheus-adapter/master/deploy/manifests/custom-metrics-apiserver-deployment.yaml -o /opt/k8s-prom/k8s-prometheus-adapter/custom-metrics-apiserver-deployment.yaml替换namespace为prom而后apply[root@linuxea k8s-prom]# kubectl apply -f k8s-prometheus-adapter/ clusterrolebinding.rbac.authorization.k8s.io/custom-metrics:system:auth-delegator created rolebinding.rbac.authorization.k8s.io/custom-metrics-auth-reader created deployment.apps/custom-metrics-apiserver created clusterrolebinding.rbac.authorization.k8s.io/custom-metrics-resource-reader created serviceaccount/custom-metrics-apiserver created service/custom-metrics-apiserver created apiservice.apiregistration.k8s.io/v1beta1.custom.metrics.k8s.io created clusterrole.rbac.authorization.k8s.io/custom-metrics-server-resources created clusterrole.rbac.authorization.k8s.io/custom-metrics-resource-reader created clusterrolebinding.rbac.authorization.k8s.io/hpa-controller-custom-metrics created确保在api-versions中出现custom.metrics.k8s.io/v1beta1[root@linuxea k8s-prom]# kubectl api-versions|grep custom.metrics.k8s.io/v1beta1 custom.metrics.k8s.io/v1beta1打开 一个代理进行curl这个api,通过这个端口curl获取指标数据[root@linuxea ~]# kubectl proxy --port=1808 Starting to serve on 127.0.0.1:1808[root@linuxea k8s-prometheus-adapter]# curl localhost:1808/apis/custom.metrics.k8s.io/v1beta1grafana仍然修改namespace为prom,并且网络类型中添加type: NodePort如果influxdb,可以注释掉[root@linuxea metrics]# kubectl apply -f grafana.yaml deployment.apps/monitoring-grafana created service/monitoring-grafana created查看下端口是否能够进行访问[root@linuxea metrics]# kubectl get pods,svc -n prom NAME READY STATUS RESTARTS AGE pod/custom-metrics-apiserver-65f545496-pj89v 1/1 Running 0 18m pod/kube-state-metrics-58dffdf67d-7sv77 1/1 Running 0 20m pod/monitoring-grafana-ffb4d59bd-hjtc4 1/1 Running 0 30s pod/prometheus-node-exporter-m74w9 1/1 Running 0 21m pod/prometheus-node-exporter-xgpqs 1/1 Running 0 21m pod/prometheus-server-65f5d59585-nx5b2 1/1 Running 0 21m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/custom-metrics-apiserver ClusterIP 10.97.212.117 <none> 443/TCP 18m service/kube-state-metrics ClusterIP 10.100.137.12 <none> 8080/TCP 21m service/monitoring-grafana NodePort 10.98.244.37 <none> 80:30980/TCP 30s service/prometheus NodePort 10.109.127.27 <none> 9090:30090/TCP 21m service/prometheus-node-exporter ClusterIP None <none> 9100/TCP 21mURL位置使用的是service名称路径,那端口就是prometheus的9090端口.http://prometheus.prom.svc:9090下载一个cluster的模板1,pod模板2,node模板3
2018年12月11日
3,421 阅读
0 评论
0 点赞
2018-12-10
linuxea:kubernetes 部署metrics-server(46)
metrics-servermetrics-server是用户开放的一个api server,这个api server用于服务资源指标服务器,并不是服务kubernetes api,更不是服务pod api,仅仅用于服务cpu利用率,内存使用率等等对象。metrics-server并不是kubernetes组成部分,只是托管在kubernetes之上的一个pod,为了能让用户使用metrics-server之上的api,在kubernetes上可以无缝使用metrics-server,可以在新的结构中这样的组织,如下:kubernetes依然正常运行,除此之外额外运行一个metrics-server,metrics-server也能提供另外一组api,这两组api合并到一起当一个使用,就需要在之前加一层代理,这个代理叫做聚合器(kube-aggregator)。这个聚合器不单单能聚合metrics-server,其他的第三方也可以聚合。这个聚合器提供的资源指标是:/apis/metrics.k8s.io/v1beta1,kubernetes默认不提供这个接口,通过metrics-server提供/apis/metrics.k8s.io/v1beta1,而kubernetes提供原生的api 群组,这两个api server通过kube-aggregator聚合器的方式整合到一起,用户访问时通过kube-aggregator,既能访问原生的api 群组,也能通过kube-aggregator访问metrics-server提供的额外群组。事实上也可以扩展其他的api,加到kube-aggregator下即可。heapster废弃后,metrics将会成kubernetes多个核心组件的先决条件,如:kubectl,top等等,如果没有metrics,这些则用不了。为了给这些组件提供数据,就要部署metrics。部署我们可以克隆kubernetes源码树中的metrics-server,也可以克隆metrics-server下的,这两个git地址不同,内容也是不同的。1,kubernetes-incubato克隆github上metrics-server的代码,而后使用1.8+版本部署[root@linuxea ~]# git clone https://github.com/kubernetes-incubator/metrics-server.git使用kubectl apply -f ./将/root/metrics-server/deploy/1.8+下的所有yaml文件部署起来[root@linuxea ~]# cd /root/metrics-server/deploy/1.8+ [root@linuxea 1.8+]# kubectl apply -f ./确保metrics-server服务成功启动[root@linuxea 1.8+]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 53d kubernetes-dashboard NodePort 10.101.194.113 <none> 443:31780/TCP 32d metrics-server ClusterIP 10.99.129.34 <none> 443/TCP 1m确保metrics-server-85cc795fbf-7srwpod启动[root@linuxea 1.8+]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE metrics-server-85cc795fbf-7srw2 1/1 Running 0 1m2,kubernetes 的cluster/addons/metrics-server中的metrics-server克隆kubernetes源码树中的metrics-server请注意,我这里使用的是kubernetes v1.11.1版本,期间重装几次,docker使用docker://18.05.0-cemetrics-server和metrics-server-nanny版本如下:提示:如果你不是这个版本,如果是更新的版本请阅读github使用文档,或者查看源码和yaml文件 - name: metrics-server image: k8s.gcr.io/metrics-server-amd64:v0.3.1 - name: metrics-server-nanny image: k8s.gcr.io/addon-resizer:1.8.3单独下载这几个文件auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml[root@linuxea metrics-server]# for i in auth-delegator.yaml auth-reader.yaml metrics-apiservice.yaml metrics-server-deployment.yaml metrics-server-service.yaml resource-reader.yaml;do wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/metrics-server/$i;done如果有以下报错,可参考如下:403 Forbidden", response: "Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=stats)E0903 1 manager.go:102] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:<hostname>: unable to fetch metrics from Kubelet <hostname> (<hostname>): Get https://<hostname>:10250/stats/summary/: dial tcp: lookup <hostname> on 10.96.0.10:53: no such hostno response from https://10.101.248.96:443: Get https://10.101.248.96:443: Proxy Error ( Connection refused )E1109 09:54:49.509521 1 manager.go:102] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:linuxea.node-2.com: unable to fetch metrics from Kubelet linuxea.node-2.com (10.10.240.203): Get https://10.10.240.203:10255/stats/summary/: dial tcp 10.10.240.203:10255: connect: connection refused, unable to fully scrape metrics from source kubelet_summary:linuxea.node-3.com: unable to fetch metrics from Kubelet linuxea.node-3.com (10.10.240.143): Get https://10.10.240.143:10255/stats/summary/: dial tcp 10.10.240.143:10255: connect: connection refused, unable to fully scrape metrics from source kubelet_summary:linuxea.node-4.com: unable to fetch metrics from Kubelet linuxea.node-4.com (10.10.240.142): Get https://10.10.240.142:10255/stats/summary/: dial tcp 10.10.240.142:10255: connect: connection refused, unable to fully scrape metrics from source kubelet_summary:linuxea.master-1.com: unable to fetch metrics from Kubelet linuxea.master-1.com (10.10.240.161): Get https://10.10.240.161:10255/stats/summary/: dial tcp 10.10.240.161:10255: connect: connection refused, unable to fully scrape metrics from source kubelet_summary:linuxea.node-1.com: unable to fetch metrics from Kubelet linuxea.node-1.com (10.10.240.202): Get https://10.10.240.202:10255/stats/summary/: dial tcp 10.10.240.202:10255: connect: connection refused]我们修改一些参数进行配置修改metrics-server-deployment.yaml中command参数,配置cpu内存大小 command: - /pod_nanny - --config-dir=/etc/config - --cpu=100m - --extra-cpu=0.5m - --memory=100Mi - --extra-memory=50Mi - --threshold=5 - --deployment=metrics-server-v0.3.1 - --container=metrics-server - --poll-period=300000 - --estimator=exponential # Specifies the smallest cluster (defined in number of nodes) # resources will be scaled to. - --minClusterSize=10并且修改metrics-server-amd64:v0.3.1的配置段,添加如下: - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP最终如下: spec: priorityClassName: system-cluster-critical serviceAccountName: metrics-server containers: - name: metrics-server image: k8s.gcr.io/metrics-server-amd64:v0.3.1 command: - /metrics-server - --metric-resolution=30s - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP # These are needed for GKE, which doesn't support secure communication yet. # Remove these lines for non-GKE clusters, and when GKE supports token-based auth. #- --kubelet-port=10255 #- --deprecated-kubelet-completely-insecure=true- --kubelet-insecure-tls这种方式是禁用tls验证,一般不建议在生产环境中使用。并且由于DNS是无法解析到这些主机名,使用- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP进行规避。还有另外一种方法,修改coredns,不过,我并不建议这样做。参考这篇:https://github.com/kubernetes-incubator/metrics-server/issues/131另外在 resource-reader.yaml 中添加 - nodes/stats,如下:[root@linuxea metrics-server]# cat resource-reader.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:metrics-server labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile rules: - apiGroups: - "" resources: - pods - nodes - nodes/stats - namespaces参考:https://github.com/kubernetes-incubator/metrics-server/issues/95apply[root@linuxea metrics-server]# pwd /root/metrics-server [root@linuxea metrics-server]# kubectl apply -f .[root@linuxea metrics-server]# kubectl get pods,svc -n kube-system NAME READY STATUS RESTARTS AGE pod/coredns-576cbf47c7-65ndt 1/1 Running 0 2m18s pod/coredns-576cbf47c7-rrk4f 1/1 Running 0 2m18s pod/etcd-linuxea.master-1.com 1/1 Running 0 89s pod/kube-apiserver-linuxea.master-1.com 1/1 Running 0 97s pod/kube-controller-manager-linuxea.master-1.com 1/1 Running 0 84s pod/kube-flannel-ds-amd64-4dtgp 1/1 Running 0 115s pod/kube-flannel-ds-amd64-6g2sm 1/1 Running 0 48s pod/kube-flannel-ds-amd64-7txhx 1/1 Running 0 50s pod/kube-flannel-ds-amd64-fs4lw 1/1 Running 0 57s pod/kube-flannel-ds-amd64-v2qvv 1/1 Running 0 48s pod/kube-proxy-bmhfh 1/1 Running 0 2m18s pod/kube-proxy-c9wkz 1/1 Running 0 50s pod/kube-proxy-d8vlj 1/1 Running 0 57s pod/kube-proxy-rpst5 1/1 Running 0 48s pod/kube-proxy-t5pzg 1/1 Running 0 48s pod/kube-scheduler-linuxea.master-1.com 1/1 Running 0 97s pod/metrics-server-v0.3.1-69788f46f9-82w76 2/2 Running 0 15s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 2m32s service/metrics-server ClusterIP 10.103.131.149 <none> 443/TCP 19s[root@linuxea metrics-server]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE metrics-server ClusterIP 10.98.186.115 <none> 443/TCP 42s此刻,metrics-server提供的metrics.k8s.io/v1beta1就能显示值啊api-versions中[root@linuxea metrics-server]# kubectl api-versions|grep metrics metrics.k8s.io/v1beta1这些已经准备完成,我们可以试试查看收集的数据[root@linuxea metrics-server]# kubectl top pods NAME CPU(cores) MEMORY(bytes) linuxea-hpa-68ffdc8b94-jjfw7 1m 103Mi linuxea-hpa-68ffdc8b94-mbgc8 1m 99Mi linuxea-hpa-68ffdc8b94-trtkm 1m 101Mi linuxea-hpa-68ffdc8b94-twcxx 1m 100Mi linuxea-hpa-68ffdc8b94-w9d7j 1m 100Mi [root@linuxea metrics-server]# kubectl top nodes NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% linuxea.master-1.com 197m 4% 3213Mi 41% linuxea.node-1.com 60m 1% 939Mi 24% linuxea.node-2.com 58m 1% 1066Mi 27% linuxea.node-3.com 127m 3% 673Mi 17% linuxea.node-4.com 47m 1% 664Mi 17%
2018年12月10日
4,363 阅读
0 评论
0 点赞
2018-12-09
linuxea:kubernetes 了解k8s资源指标(45)
我们在之前知道heapster在1.113后将完全启用。在资源指标中分为资源指标和自定义指标,先前的heapster就提供了资源收集存储和监控基本的功能,并且支持多个存储接收器,如:InflxDB等。这些组件均由第三方提供,由于某些不稳定的因素,heapster整合了十多个后端存储适配器,匹配这些适配器同时也增加了代码量,并且尚未得到改善,由此可见,这种架构下,heapster并不是很适用于后期的稳定发展。heapster是一个原始的时间序列存储数据库,每个接收器都作为核心代码的一部分,使得整个监控结构定义越来越麻烦。我们知道kuberntes是非常灵活可扩展的,替换heapster,并不困难。现有的版本中,支持开发人员定义API服务器扩展核心API服务,一些特殊应用程序可以进行扩展到kuerntes支持的资源类型中,一般情况,有三种方式:CRD:自定义资源指标,自定义API server,修改源码定义在kubernetes中,有一种方式可以使开发人员轻松使用自己的API服务器,来扩展附加到已有的kubernetes之上,聚合进更多新的功能在kubernetes集群中,api server支持那些组件,都是kubernetes事先定义好的,如果我们想要的组件,这里面没有的话,就可以自己开发api server,并且可以单独运行,也可以托管到kubernetes上运行,然后在kubernetes服务器和开发的api server前段添加代理服务,而后所有对api server的请求,既能获取已有的api,也能获取自己开发定义的api server。像这种就成为聚合器。如下:在1.8中引入了资源指标API,资源内容当作接口数据获取,和早先的heapster本身自己提供不同,传统的heapster和API是不同的,在1.8之前是没有引入API的,在之后引入了APi资源指标,整合到一起。在1.6引入了自定义指标。有一些组件是依赖这些指标的,如kubectl top命令,如果没有一个收集资源指标的供给,是无法正常运行的。另外像HPA(水平pod自动伸缩器),这些还是需要根据获取当前pod的资源情况定义。比如CPU占用量已经达到百分之80,负载较高就添加pod,如果CPU 占用率低于百分之五,就删减几个pod。我们知道无论pod运行与否,只要pod定义了requests,只要被调度,就会调度到某个节点上,节点上的资源就会预留给pod使用,如果这个pod空闲,那就会浪费资源。可以将这个pod移出,从而腾出更多的空间以供应其他的pod使用。这些组件都是依赖资源指标才能工作的,早期都是依赖heapster才能实现。比如早期在kubernetes之上必须部署heapster才能使用top命令,另外才能使用hpa,对deployment之下的pod做水平自动伸缩。此前这些指标只能让heapster提供,并且都是很有限度的,伸缩数据能力只能根据CPUY用量来伸缩,并不能根据io,内存,网卡等,heapster是做不到的。我们期望使用越来越多的指标来做,比如:cpu利用率都很低。而pod并发访问量很大,可能这时候已经需要添加pod了,但是这时候并不能根据并发指标来做。所以,仅仅根据cpu不足以反馈应用伸缩的场景,这时候就需要引入更多的其他的指标。这时候就出现了新的资源指标模型,以及更多的自定义指标模型。新的资源指标获取的主要方式,是通过metrics-server来实现的。prometheus用来也允许开始的自定义指标的有一些监控系统,如prometheus,prometheus已经被收入到cncf(云原生计算基金会构建可持续生态系统 Cloud Native Computing Foundation)下的項目,第一個是kubernetes,第二个则是prometheus。prometheus能收集各种维度的指标,如:CPu,内存,io,流量等等,这些数据被整合到kubernetes中,让kubernetes能够拿来作为判断是否来伸缩pod规模的基本标准。后来,自定义指标通过prometheus来使用,即作为监控系统,有作为特殊资源指标提供,这些指标可自定义指标。新的架构中有核心指标和监控:核心指标包括主要指kubelet,metrics-server以及由api server提供的api组件组成。其中CPU累计使用率(累计使用时长占整个CPU使用总执行时间),内存实时使用率,pod资源占用率,容器磁盘占用率。除了这些之外,可能还要去评估网络质量,链接数量,带宽等等,这些就需要第三方工具使用。而核心指标是不能委托给第三方的,核心指标会被一些核心组件使用,如:kubectl top,dashboard都会用到,所以这些称为核心指标。监控指标: 用于系统收集各种指标数据并提供终端用户,并不限于内存,pod资源占用磁盘使用,存储系统以及HPA等等。hpa不单单可以使用核心指标有也可以使用监控自定义的扩展指标。监控指标就成为非核心指标,也包含一些核心指标,除此之外还能包含很多其他的指标。这些非核心指标本身是无法被kubernetes解析的。prometheus是可以理解的,而kunernetes是无法理解的,这也就是为什么需要一个k8s-prometheus-adapter的原因。我们需要将prometheus采集的数据转换成kubernetes理解的格式。k8s本身不提供这样的组件,如果用户不打算使用prometheus,就可以不用部署,但是核心的核心指标组件是必须要部署的。核心指标组件早期是heapster提供的,1.12彻底废弃,核心指标就交给metrics-server聚合提供。
2018年12月09日
2,925 阅读
0 评论
0 点赞
2018-12-07
linuxea:kubernetes heapster安装配置(44)
在docker中可以使用那个stats查看容器的资源使用,而在Kubernetes中可以使用top查看。但是一般都会报错,如下:[root@linuxea metrics]# kubectl top pod Error from server (NotFound): the server could not find the requested resource (get services http:heapster:) [root@linuxea metrics]# top命令应用依赖于heapster实现这个功能,在kubenretes上需要一个运行在集群级别的,各个pod,甚至各个节点的资源用量的采集,已经存储工具。top是根据这些采集和存储获取数据,而后显示的。如果没有heapster采集存储,top命令是无法运行的。此前的dashboard的一部分用量也是依赖于heapster的。在节点上,使用top等命令是用来统计节点的资源使用情况,当kubernetes运行在众多节点上后, 每一个pod运行在哪里,如果事先不做一些处理,默认是无法确定的。如何使用一个统一的视图来查看,必须要在每个节点部署一个统一的一个资源指标收集和存储工具,至少要有一个收集工具。当需要查看的时候,可以连接到每一个节点之上,通过本地的agent获取节点上的进程,以及节点本身的资源用量。而后显示top中单独的部署,heapster只是一个汇聚工具,每个节点需要采集节点自身的和节点之上pod的指标数据,但是这些数据只是在节点自身上,因此,需要一个集中统一来收集并且存储的工具。架构在每个节点上都运行一个重要的组件:kubelet。kubelet是可以获取由他创建的pod的资源数据的,在kubelet下真正完成采集pod的数据的是kubelet子组件cAdvisor(cAdvisor目前是内建的功能)。cAdvisor专门用来收集当前节点上各pod上各个容器的资源用量,以及节点之上的资源用量和存储用量等等信息。早期收集完成后,是提供端口,可进行在节点上查看。现在是主动报告数据到heapster,而后heapster收集每个节点上运行的heapster采集到的数据在集群之上托管heapster,各个cAdvisor主动向heapster发送采集到的数据。如果没有存储,默认是存储在内存中,但是内存是有限的。这样一来就不能够查看到历史数据。查看历史数据就需要InfluxDB,heapster收集到数据后整合到InfluxDB,这样就能完成持久存储的目的。并且使用Grafana来查看数据源为InfluxDB中的数据。完成展示数据。如下图另外还需要设置RBAC的资源控制权限pod资源监控资源分为三类指标:kuberntes系统指标,容器指标,业务指标influxDBinfluxDB是一个时序数据库系统,InfluxDB被heapster依赖,所以先部署influxDB一般在生产环境中,这里的influxDB最好使用有持久功能的存储卷来做数据存储,在github的heapster中,使用的是 volumes: - name: influxdb-storage emptyDir: {}下载github之上的这个yaml文件[root@linuxea metrics]# curl -Lk https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/influxdb.yaml -o $PWD/influxdb.yaml % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 960 100 960 0 0 1199 0 --:--:-- --:--:-- --:--:-- 1200下载之后,可以直接启动,也可以apiVersion:apps/v1,如果要修改,需要添加selectorspec: replicas: 1 selector: matchLabels: task: monitoring k8s-app: influxdbapply[root@linuxea metrics]# kubectl apply -f influxdb.yaml deployment.apps/monitoring-influxdb created service/monitoring-influxdb created[root@linuxea metrics]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE monitoring-influxdb-848b9b66f6-4wtfb 1/1 Running 0 8s[root@linuxea metrics]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 49d kubernetes-dashboard NodePort 10.101.194.113 <none> 443:31780/TCP 28d monitoring-influxdb ClusterIP 10.99.135.180 <none> 8086/TCP 55s也可以通过查看日志来了解启动是否ok kubectl logs -n kube-system monitoring-influxdb-848b9b66f6-4wtfb[root@linuxea metrics]# kubectl logs -n kube-system monitoring-influxdb-848b9b66f6-4wtfb ts=2018-11-04T11:47:18.945900Z lvl=info msg="InfluxDB starting" log_id=0BZdcP8G000 version=unknown branch=unknown commit=unknown ts=2018-11-04T11:47:18.945924Z lvl=info msg="Go runtime" log_id=0BZdcP8G000 version=go1.10.3 maxprocs=4 ts=2018-11-04T11:47:58.951399Z lvl=info msg="Using data dir" log_id=0BZdcP8G000 service=store path=/data/data ts=2018-11-04T11:47:58.951575Z lvl=info msg="Open store (start)" log_id=0BZdcP8G000 service=store trace_id=0BZdeqPl000 op_name=tsdb_open op_event=start ts=2018-11-04T11:47:58.951672Z lvl=info msg="Open store (end)" log_id=0BZdcP8G000 service=store trace_id=0BZdeqPl000 op_name=tsdb_open op_event=end op_elapsed=0.100ms ts=2018-11-04T11:47:58.951762Z lvl=info msg="Opened service" log_id=0BZdcP8G000 service=subscriber ts=2018-11-04T11:47:58.951776Z lvl=info msg="Starting monitor service" log_id=0BZdcP8G000 service=monitor ts=2018-11-04T11:47:58.951781Z lvl=info msg="Registered diagnostics client" log_id=0BZdcP8G000 service=monitor name=build ts=2018-11-04T11:47:58.951785Z lvl=info msg="Registered diagnostics client" log_id=0BZdcP8G000 service=monitor name=runtime ts=2018-11-04T11:47:58.951824Z lvl=info msg="Registered diagnostics client" log_id=0BZdcP8G000 service=monitor name=network ts=2018-11-04T11:47:58.951831Z lvl=info msg="Registered diagnostics client" log_id=0BZdcP8G000 service=monitor name=system ts=2018-11-04T11:47:58.951897Z lvl=info msg="Starting precreation service" log_id=0BZdcP8G000 service=shard-precreation check_interval=10m advance_period=30m ts=2018-11-04T11:47:58.952047Z lvl=info msg="Starting snapshot service" log_id=0BZdcP8G000 service=snapshot ts=2018-11-04T11:47:58.952060Z lvl=info msg="Starting continuous query service" log_id=0BZdcP8G000 service=continuous_querier ts=2018-11-04T11:47:58.951957Z lvl=info msg="Storing statistics" log_id=0BZdcP8G000 service=monitor db_instance=_internal db_rp=monitor interval=10s ts=2018-11-04T11:47:58.952114Z lvl=info msg="Starting HTTP service" log_id=0BZdcP8G000 service=httpd authentication=false ts=2018-11-04T11:47:58.952155Z lvl=info msg="opened HTTP access log" log_id=0BZdcP8G000 service=httpd path=stderr ts=2018-11-04T11:47:58.952232Z lvl=info msg="Listening on HTTP" log_id=0BZdcP8G000 service=httpd addr=[::]:8086 https=false ts=2018-11-04T11:47:58.952253Z lvl=info msg="Starting retention policy enforcement service" log_id=0BZdcP8G000 service=retention check_interval=30m ts=2018-11-04T11:47:58.952449Z lvl=info msg="Listening for signals" log_id=0BZdcP8G000rbac下载github的rbac[root@linuxea metrics]# curl -Lk https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/rbac/heapster-rbac.yaml -o $PWD/heapster-rbac.yaml[root@linuxea metrics]# kubectl apply -f heapster-rbac.yaml clusterrolebinding.rbac.authorization.k8s.io/heapster createdheapster其中heapster用户名是被绑定在ClusterRole上运行的,可查看rbac的yaml文件。[root@linuxea metrics]# curl -Lk https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/heapster.yaml -o $PWD/heapster.yaml其中- --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086指定influxDB的pod名称,这个名称可被解析为了方便访问,我们加上NodePortspec: ports: - port: 80 targetPort: 8082 type: NodePortapply[root@linuxea metrics]# kubectl apply -f heapster.yaml serviceaccount/heapster created deployment.apps/heapster created service/heapster created [root@linuxea metrics]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE heapster NodePort 10.109.4.29 <none> 80:32154/TCP 11s[root@linuxea metrics]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE heapster-84c9bc48c4-lwlk7 1/1 Running 0 1m并且可以通过日志查看是否准备妥当[root@linuxea metrics]# kubectl logs -f heapster-84c9bc48c4-lwlk7 -n kube-system I1104 12:03:48.305225 1 heapster.go:78] /heapster --source=kubernetes:https://kubernetes.default --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086 I1104 12:03:48.305268 1 heapster.go:79] Heapster version v1.5.4 I1104 12:03:48.305424 1 configs.go:61] Using Kubernetes client with master "https://kubernetes.default" and version v1 I1104 12:03:48.305466 1 configs.go:62] Using kubelet port 10255 E1104 12:05:57.947315 1 influxdb.go:297] issues while creating an InfluxDB sink: failed to ping InfluxDB server at "monitoring-influxdb.kube-system.svc:8086" - Get http://monitoring-influxdb.kube-system.svc:8086/ping: dial tcp 10.99.135.180:8086: getsockopt: connection timed out, will retry on use I1104 12:05:57.947337 1 influxdb.go:312] created influxdb sink with options: host:monitoring-influxdb.kube-system.svc:8086 user:root db:k8s I1104 12:05:57.947358 1 heapster.go:202] Starting with InfluxDB Sink I1104 12:05:57.947363 1 heapster.go:202] Starting with Metric Sink I1104 12:05:57.954628 1 heapster.go:112] Starting heapster on port 8082此后,通过浏览器访问试试grafana在grafana的yml文件中挂载了两个存储卷,一个是存放数据,一个是https证书,存放位置/etc/ssl/certs,如要使用自己的则需要存放在/etc/ssl/certs之下并且传递了INFLUXDB_HOST和GF_SERVER_HTTP_PORT的变量参数[root@linuxea metrics]# curl -Lk https://raw.githubusercontent.com/kubernetes/heapster/master/deploy/kube-config/influxdb/grafana.yaml -o $PWD/grafana.yaml我们通过集群外部访问,添加NodePort,并且设置端口为30980 ports: - name: http port: 80 targetPort: 3000 nodePort: 30980 protocol: TCP type: NodePort selector: k8s-app: grafanapply[root@linuxea metrics]# kubectl apply -f grafana.yaml deployment.apps/monitoring-grafana created service/monitoring-grafana unchanged[root@linuxea metrics]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE heapster NodePort 10.109.4.29 <none> 80:32154/TCP 26m kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 49d kubernetes-dashboard NodePort 10.101.194.113 <none> 443:31780/TCP 28d monitoring-grafana NodePort 10.103.116.252 <none> 80:30980/TCP 4s[root@linuxea metrics]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE heapster-84c9bc48c4-lwlk7 1/1 Running 0 18m kubernetes-dashboard-767dc7d4d-q6ls7 1/1 Running 0 6d monitoring-grafana-555545f477-hpz85 1/1 Running 0 1m monitoring-influxdb-848b9b66f6-4wtfb 1/1 Running 0 34m在集群外通过30980访问集群内的任何一台ip:30980即可heapster在1.13彻底弃用。可参考:Grafana和Heapster,可以试试其他模板下载使用。
2018年12月07日
3,671 阅读
0 评论
0 点赞
2018-12-04
linuxea:kubernetes 了解容器资源需求与限制(43)
之前介绍的pod资源调度,此篇主要记录的是kubernetes上运行pod的对象的时,如何去监控系统级的一些资源指标,业务指标的获取,以及监控。容器在启动的时候,可以根据资源需求,配置资源限额的,如CPU,内存。而CPU资源属于可压缩资源,一个容器在本应该获取指定的资源获取不到的时候,进行等待即可,而内存则不一样。内存属于非可压缩资源,如果内存资源因为指定的大小而不够的时候会因为内存资源耗尽而被Kill。此前我们知道,在kubernetes中资源可定义为起始和终结值。requests定义cpu和内存的使用率。至少需要用的资源需求。limits限制,最高消耗区间。并且是硬限制一般来讲limis应该大于等于requests,尽管这些限制是应用在容器之上的,但是我们称之pod资源需求,也是应用到pod上的。CPU在kubernetes上一个单位的CPU相当于一颗虚拟CPU(虚拟CPU指一个核心或者一个超线程。一个两核双线程的CPU可以虚拟4颗逻辑CPU)。而且一个CPU并且能够被划分子单位,一核,相当于1000 millcores(微核),那么500m就相当于0.5个CPU内存内存的计量单位是E,P,T,G,M,K Ei,Pi,Ti,Gi,Mi,Ki 假设,我们限制每个pod的cpu只能使用0.5个核心,设置成cpu.limits=500m,这个cpu.limits=500m指的是硬上限,也就是说最多使用500m,不用就不用。如下图:除此之外还有requests,requests是说,如果想要确保正常运行容器,至少要给0.2个核心。但是这个0.2个核心并不是说直接就是用到0.2个,而是说至s少要保证有0.2个能够被使用,并且调度的目标节点至少有0.2个空闲的cpu资源可用。每一个节点已经有多少CPU资源被分配出去,就是计算这个节点上所运行的所有容器的CPU requests加起来的,这个加起来的值被总核心减掉,剩下的就是未被分配的。如:调度4个容器,每个容器至少需要0.5核心,那就意味着还剩下2核心空闲。如果此刻pod中至少有一个容器要使用三个CPU,那么这个节点就不被预选,无法满足Pod。定义的资源需求,只是定义了资源的请求下限。如果我们明确说只要200m(requests)资源来运行,系统有4核心,而运行的pod因为bug的原因,是有可能将4核心全部占用的。因为只是定义了200m的资源需求。一般情况下,需求和上限都需要同时定义,否则就有可能推掉节点的所有资源requests需求确保在调度时候,对应节点上需已经拥有这么多的资源以便于满足这个pod运行的基本需求。而limits用于限制这个容器无论怎么运行绝对不能超过的资源阈值。定义测试资源需求是定义在容器级别的,在pods.spec.containers.resources:pec.containers[].resources.limits.cpuspec.containers[].resources.limits.memoryspec.containers[].resources.requests.cpuspec.containers[].resources.requests.memory参考Pod和Container的资源请求和限制,定义资源限制需要在容器级别加resources,而后requests下定义两个维度的需求,分别是cpu和memory(可以同时定义也可以定义一个)。再者,为了屏蔽,定义limits限制上限多少,达到这个上限就不再分配资源。并且也可只定义需求,而不定义限制。也可以只定义限制而不定义需求。需求和限制都可以只定义一个 ,一般来讲,都会定义完整。很多情况下,requests和limits分别对应的是需求级别和上限级别,一般的话requests和limits定义相同是合适的如下:定义requests的CPU为300m,也就是0.3核心的CPU,内存为256M,而限制定义为最多用1核心的CPU,最多使用512的内存。延续内容:如果这个pod一直使用300m。那么定义的限制上限资源就不起作用,剩下的200M只是存在于定义的列表中,并不是说还有200M在等待,200M仍然可别其他所使用。仅仅作为上限限制。spec: containers: - name: linuxea-pod1-com image: "marksugar/nginx:1.14.a" resources: requests: cpu: "300m" memory: "256Mi" limits: cpu: "1" memory: "512Mi"我们借用别人的pod进行压测一下,yml如下apiVersion: v1 kind: Pod metadata: name: pod-demo-linuxea namespace: default labels: www: linuxea-com tier: backend spec: containers: - name: linuxea-pod1-com image: "ikubernetes/stress-ng" command: ["/usr/bin/stress-ng","-c 1","--metrics-brief"] ports: - containerPort: 88 resources: requests: cpu: "300m" memory: "256Mi" limits: cpu: "1" memory: "512Mi"[root@linuxea metrics]# kubectl apply -f pod-demo.yaml pod/pod-demo-linuxea created[root@linuxea metrics]# kubectl get pods NAME READY STATUS RESTARTS AGE dpment-linuxea-7748786749-4s2qv 1/1 Running 0 5d dpment-linuxea-7748786749-6llcz 1/1 Running 0 5d dpment-linuxea-7748786749-dv4nf 1/1 Running 0 5d pod-demo-linuxea 1/1 Running 0 38s而后使用top命令查看压测结果此刻CPU的占用率是%25 。我机器上4核CPU,在yaml的limits中最大用1核心,100的4分之一是25%[root@linuxea metrics]# kubectl exec pod-demo-linuxea top Mem: 3191756K used, 4982256K free, 405912K shrd, 944K buff, 2204020K cached CPU: 25% usr 0% sys 0% nic 75% idle 0% io 0% irq 0% sirq Load average: 1.00 0.71 0.33 3/533 31 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 7 1 root R 6896 0% 2 25% {stress-ng-cpu} /usr/bin/stress-ng 1 0 root S 6256 0% 3 0% /usr/bin/stress-ng -c 1 --metrics- 8 0 root S 1516 0% 2 0% top 14 0 root S 1516 0% 2 0% top 20 0 root S 1516 0% 1 0% top 26 0 root R 1512 0% 0 0% topresources定义能够被调度器作为基础衡量条件的调度指数使用的。对于每个节点来讲,会将所有容器的资源需求量加起来作为已分配出去的配额,limits上限是非常有效的容器可见资源和可用资源当使用resources限制了资源需求和限额后,使用free命令查看,显示的是节点上的所有内存,并不是容器的配额内存。这样是有问题的。如:jvm在跑起来的时候,虚拟机启动时候就会创建堆,而后类,数组等都由此分配。堆的分配当然使用的是物理机的内存,或者多少。如果jvm跑在容器内,jvm拿到的内存是节点物理内存量,而不是容器limits的配额内存,那么计算的结果肯定是有问题的,吞掉容器所有内存都不够,甚至出现其他问题。Qosqos是作为服务质量的一个简称当限制了一些资源后,默认会自动属于某个Qos的类。默认情况下,类别有三个:Guranteed:每个容器每个相同资源,同时设置了相同的resources,limits,必须满足相同的条件: cpu.limits=cpu.requests memory.limits=memory.requests大致如此: resources: requests: cpu: "1" memory: "512Mi" limits: cpu: "1" memory: "512Mi"这样相同的配置就会自动归类的Guranteed,这类pod拥有最高优先级。如: 资源不够的时候,优先运行这类资源Burstable:至少有一个容器至少有一个容器设置了cpu或者内存的limits属性,或者至少有一个容器设置了cpu或者内存的requests属性,这类的具有中等优先级。此前,我们创建的pod,cpu内存的requests和limits不相同,便是Burstable类型[root@linuxea metrics]# kubectl describe pods pod-demo-linuxea |grep QoS QoS Class: BurstableBestEffort: 没有任何一个容器没有任何一个容器设置了requests或者limits;最低优先级别。当资源不够用的时候,属于BestEffort的容器将会被优先关闭。优先让属于其他两种pod类型的资源运行。如果资源仍然不够,就会关闭Burstable类的pod容器。如果此时Burstable的容器已经全部关闭,或者说只有Guranteed,但是在资源还是不够用。就会依据已占用量和需求量的比例大的优先被关闭。如下:上面pod limits是1G,requests基本使用是512M,而占用了最低需求的500M。基本需求并不会启动就全部占用下面pod limits是2G,requests基本使用是1G,而占用了基本需求的800M。第一个pod的已经分配的量已经接近使用的量,requests是512M,已经使用了500M。而后面的pod已经占用量与基本要求的量差距较大,requests是1G,占用量是800M。因此资源紧缺的情况下,关闭第一个pod。这种方式给予已占用量与需求量的比例来做决策,比例大的优先被关闭。此前节点有污点,为了方便使用,将污点untainted[root@linuxea metrics]# kubectl taint node linuxea.node-1.com node_type- node/linuxea.node-1.com untainted [root@linuxea metrics]# kubectl taint node linuxea.node-2.com node_type- node/linuxea.node-2.com untainted [root@linuxea metrics]# kubectl taint node linuxea.node-3.com node_type- node/linuxea.node-3.com untainted [root@linuxea metrics]#
2018年12月04日
2,464 阅读
0 评论
0 点赞
2018-12-02
linuxea:kubernetes 节点污点调度与pod容忍度(42)
在前面的两种方式中,都是由pod去选择的,节点被动选择运行。而污点调度方式就给了节点的选择权。让节点可以选择让那些pod运行在节点上。总的来说,污点就是定义在节点上的键值属性数据。此前,我们知道,键值属性有三类,第一类叫标签,第二类叫注解,第三类便是污点。污点用在节点之上,而前两类所有资源对象都可以使用。pod亲和性和node亲和性都是pod的属性,而污点是节点的属性污点也是一种键值属性,主要用来让节点拒绝那些不能容忍的pod,因此需要在pod对象上定义容忍度。而容忍度也是pod对象上的第三类键值数据,并且是一个列表。kubernetes分别有一个预选策略PodToleratesNodeTaints和优选函数taint_toleration,分别完成基于所谓的污点和容忍度的调用逻辑,并且作为选择中标准的一种来进行定义。污点定义在node.spec.taints:effect定义当pod不能容忍这个污点时, 采取的行为是什么。这种排斥的效果有三种,分别是:Noschedule: 仅仅影响调度过程,对现存的pod对象不产生影响。如果不能容忍,就不进行调度。NoExecute: 不仅影响调度,也影响现存pod对象; 如果不能容忍的pod将会被驱逐。PreferNoschedule:不能容忍就不能调度,但是如果没有其他地方运行,那也可以。keytimeAddedvalue 可以为空在pod对象上定义容忍度的时候,还支持两种操作,等值比较,存在性判断等值比较容忍度与污点必须在key,value和effect上完全匹配,存在性判断表示二者的key,timeAdded必须匹配,value 可以为空另外一个节点可以配置多个污点,一个pod也可以有多个容忍度,只不过两者匹配的时候需要遵循以下逻辑:1,检查每个有着容忍匹配容忍度的污点,不能匹配到的污点如果存在,如果有一个使用Noschedule标识,pod就无法调度我们在pod上定义三个容忍度,在节点之上定义两个污点。如果容忍度中只包含了容忍了一个污点,那将只会匹配一个污点,这样的情况是存在的!所以我们要检查这种匹配度有多高!事实上这个pod不一定会运行在这个节点之上的。如下图:逐一检查容忍度和对方的污点相匹配,节点上的每一个污点都需要被容忍,如果存在一个不被容忍,就需要看这个污点的条件。如果污点是effect.PreferNoschedule,那就可以运行的。如果是Noschedule就不能调度成功。如上图。如果至少有一个污点不匹配,如果是NoExecute,且节点已经运行有此pod,此pod将被驱逐。总结:如果一个节点定义了污点,一个pod能否调度上来。首先检查能够被匹配到的污点和容忍度,检查完能够被容忍的污点后,检查不能够被容忍度容忍的污点,检查不能够被容忍度容忍污点,就检查effect 排斥的三种行为,如果是PreferNoschedule就可以继续调度,如果是Noschedule,且pod尚未调度到节点,就不能被调度到节点,Noschedule调度之前已经运行在节点的的pod仍然能够运行。如果是NoExecute,且pod尚未调度到节点,就不能被调度到节点,而且此前调度过来的已经运行的pod,如果被修改了污点,就意味着运行的这个pod也会被驱逐。在master节点上,就是有污点的.NoSchedule.如果pod不能够容忍这个污点,pod就不能够调度到master节点上[root@linuxea schedule]# kubectl describe node linuxea.master-1.com|grep Taints Taints: node-role.kubernetes.io/master:NoSchedule并且master这个污点在启动的时候就被打上去。如果pod不能够容忍这个污点,就不会调度到master这个节点上,而一些其他的kubernetes组件肯定是容忍这个污点的。否则将调度不到master上,像api server就是NoExecute[root@linuxea schedule]# kubectl describe pods kube-apiserver-linuxea.master-1.com -n kube-system|grep Tolerations Tolerations: :NoExecute另外还有flannel,flannel就更清楚地标记容忍度,包含master 污点node-role.kubernetes.io/master,并且是NoSchedule。这些信息就影响这调度[root@linuxea schedule]# kubectl describe pods kube-flannel-ds-amd64-mnrwp -n kube-system Node-Selectors: beta.kubernetes.io/arch=amd64 Tolerations: node-role.kubernetes.io/master:NoSchedule node.kubernetes.io/disk-pressure:NoSchedule node.kubernetes.io/memory-pressure:NoSchedule node.kubernetes.io/not-ready:NoExecute node.kubernetes.io/unreachable:NoExecute Events: <none>管理节点污点NoSchedule此刻有三个节点,将node1标记为线上,容忍行为效果是NoSchedule。pod不运行在node1,node1只会运行生产pod[root@linuxea schedule]# kubectl taint node linuxea.node-1.com node_type=produce:NoSchedule node/linuxea.node-1.com tainted随意apply几个pod,不设置容忍度apiVersion: apps/v1 kind: Deployment metadata: name: dpment-linuxea namespace: default spec: replicas: 3 selector: matchLabels: app: linuxea_app version: v0.1.32 template: metadata: labels: app: linuxea_app version: v0.1.32 spec: containers: - name: nginx-a image: marksugar/nginx:1.14.b ports: - name: http containerPort: 80apply[root@linuxea schedule]# kubectl apply -f demo.yaml deployment.apps/dpment-linuxea created在查看,pod运行在node2和node3,跳过了node1[root@linuxea schedule]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-648d599b5f-j68cb 1/1 Running 0 5s 172.16.5.20 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-sh2tn 1/1 Running 0 5s 172.16.4.26 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-vrjtl 1/1 Running 0 5s 172.16.5.21 linuxea.node-3.com <none>甚至,我们可以删掉在apply一次[root@linuxea schedule]# kubectl delete -f demo.yaml deployment.apps "dpment-linuxea" deleted这些pod没有设置node上的容忍度,仍然不会调度到node1,说明污点是有效的。[root@linuxea schedule]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-648d599b5f-hc9n6 1/1 Running 0 5s 172.16.4.27 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-kjsgd 1/1 Running 0 5s 172.16.5.22 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-wp4pz 1/1 Running 0 5s 172.16.4.28 linuxea.node-2.com <none>NoExecute此刻,尝试NoExecute。现在node2节点上运行了一个pod,我们在node2上在打一个污点node_type=dev:NoExecute,并且是容忍的行为是NoExecute,也就是说,如果node2上的pod不是污点dev的,并且此前运行不是dev的pod,也会被驱逐[root@linuxea schedule]# kubectl taint node linuxea.node-2.com node_type=dev:NoExecute node/linuxea.node-2.com taintednode2上的pod没有容忍这个污点,被驱逐了,但是还有node3没有任何污点,所以运行在node3之上[root@linuxea schedule]# kubectl get pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-648d599b5f-87jhp 1/1 Running 0 12s 172.16.5.23 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-fgwhd 1/1 Running 0 12s 172.16.5.25 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-hc9n6 1/1 Terminating 0 31m 172.16.4.27 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-kjsgd 1/1 Running 0 31m 172.16.5.22 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-wp4pz 1/1 Terminating 0 31m 172.16.4.28 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-hc9n6 0/1 Terminating 0 31m 172.16.4.27 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-hc9n6 0/1 Terminating 0 31m 172.16.4.27 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-hc9n6 0/1 Terminating 0 31m 172.16.4.27 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-hc9n6 0/1 Terminating 0 31m 172.16.4.27 linuxea.node-2.com <none> dpment-linuxea-648d599b5f-wp4pz 0/1 Terminating 0 31m <none> linuxea.node-2.com <none> dpment-linuxea-648d599b5f-wp4pz 0/1 Terminating 0 31m <none> linuxea.node-2.com <none> dpment-linuxea-648d599b5f-wp4pz 0/1 Terminating 0 31m <none> linuxea.node-2.com <none>而后都运行在node3之上,如果node3也有污点,且pod不能容忍,那就会pending.[root@linuxea schedule]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-648d599b5f-87jhp 1/1 Running 0 1m 172.16.5.23 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-fgwhd 1/1 Running 0 1m 172.16.5.25 linuxea.node-3.com <none> dpment-linuxea-648d599b5f-kjsgd 1/1 Running 0 32m 172.16.5.22 linuxea.node-3.com <none>管理Pod容忍度在pods.spec.tolerations字段中tolerationSeconds 表示,如果被驱逐,驱逐前等待时间。默认0秒 ,立即被驱逐key 列表operator 操作符Exists : 判断污点存在与否,存在就可以,且不管是什么值都匹配Equal: 容忍度必须能够精确容忍对方的污点值在上述中,使用Exists ,只要是node_type在就容忍,如果是Equal,只要是node_type且要么容忍dev污点值,元要么produce的污点值,需要明确指定我们先将linuxea.node-3.com添加污点node_type=Pre-production:NoSchedule,容忍行为NoSchedule[root@linuxea schedule]# kubectl taint node linuxea.node-3.com node_type=Pre-production:NoSchedule node/linuxea.node-3.com tainted此刻在apply 刚才没有容忍度的pod就会pending[root@linuxea schedule]# kubectl get pods NAME READY STATUS RESTARTS AGE dpment-linuxea-648d599b5f-cxfv6 0/1 Pending 0 3s dpment-linuxea-648d599b5f-ghphv 0/1 Pending 0 3s dpment-linuxea-648d599b5f-rvpw2 0/1 Pending 0 3sNoExecute此刻使用NoExecute也会pending.因为污点和容忍度不完全等。如下:首先操作符为Equal,精确容忍,而node1的污点node_type:produce的容忍行为是NoSchedule,而在文件中定义的是容忍行为是NoExecute,唯一的键值匹配produce也不符合NoExecutetolerationSeconds表示,一旦容忍将在30秒后进行驱逐综上所述,pod没有容忍任何node的污点,所以pending tolerations: - key: "node_type" operator: "Equal" value: "produce" effect: "NoExecute" tolerationSeconds: 30完整yamlapiVersion: apps/v1 kind: Deployment metadata: name: dpment-linuxea namespace: default spec: replicas: 3 selector: matchLabels: app: linuxea_app version: v0.1.32 template: metadata: labels: app: linuxea_app version: v0.1.32 spec: containers: - name: nginx-a image: marksugar/nginx:1.14.b ports: - name: http containerPort: 80 tolerations: - key: "node_type" operator: "Equal" value: "produce" effect: "NoExecute" tolerationSeconds: 30 NoSchedule使用NoSchedule就不需要指定tolerationSeconds的驱逐时间,因为NoSchedule只会拒绝不能容忍的,对于在上一次已经运行的pod不驱逐操作符精确匹配具有污点为node_type为produce的节点而node_type为produce污点的节点是node1精确满足容忍度的节点是node1,这三个pod将会调度到node1上。如下: tolerations: - key: "node_type" operator: "Equal" value: "produce" effect: "NoSchedule" # tolerationSeconds: 10yaml如下[root@linuxea schedule]# cat demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: dpment-linuxea namespace: default spec: replicas: 3 selector: matchLabels: app: linuxea_app version: v0.1.32 template: metadata: labels: app: linuxea_app version: v0.1.32 spec: containers: - name: nginx-a image: marksugar/nginx:1.14.b ports: - name: http containerPort: 80 tolerations: - key: "node_type" operator: "Equal" value: "produce" effect: "NoSchedule" # tolerationSeconds: 10apply[root@linuxea schedule]# kubectl apply -f demo.yaml deployment.apps/dpment-linuxea configured而后就调度到具有kye是node_type:produce,行为是NoSchedule污点的node1之上,因为yaml文件中容忍了node1的污点[root@linuxea schedule]# kubectl get pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-df4b6f749-5jlcb 1/1 Running 0 5s 172.16.3.4 linuxea.node-1.com <none> dpment-linuxea-df4b6f749-rzndk 1/1 Running 0 4s 172.16.3.5 linuxea.node-1.com <none> dpment-linuxea-df4b6f749-wwpck 1/1 Running 0 3s 172.16.3.6 linuxea.node-1.com <none>Exists我们在改改,修改成污点只要键是node_type的就容忍,也就是只要键是node_type的污点都调度到上面,将操作符改成Exists,我们知道Exists,只要是匹配到的就可以被容忍,如果没有其他的条件的话上述中,node污点分别是:linuxea.node-1.com node_type=produce:NoSchedulelinuxea.node-2.com node_type=dev:NoExecutelinuxea.node-3.com node_type=Pre-production:NoScheduleyaml修改后如下 tolerations: - key: "node_type" operator: "Exists" value: "" effect: "NoSchedule"注意:尽管污点的键值在三个节点都是node_type。但是node1和node3的行为效果是NoSchedule,而node2行为效果是NoExecute,因为行为效果不同,所以也只会调度在node1和node3的污点节点上yaml完整如下:apiVersion: apps/v1 kind: Deployment metadata: name: dpment-linuxea namespace: default spec: replicas: 3 selector: matchLabels: app: linuxea_app version: v0.1.32 template: metadata: labels: app: linuxea_app version: v0.1.32 spec: containers: - name: nginx-a image: marksugar/nginx:1.14.b ports: - name: http containerPort: 80 tolerations: - key: "node_type" operator: "Exists" value: "" effect: "NoSchedule"apply[root@linuxea schedule]# kubectl apply -f demo.yaml deployment.apps/dpment-linuxea configuredapply后会进行重新调度,调度后到了node1和node3之上[root@linuxea schedule]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-798ff6bc87-8kpw2 1/1 Running 0 12s 172.16.5.33 linuxea.node-3.com <none> dpment-linuxea-798ff6bc87-9fgn4 1/1 Running 0 14s 172.16.3.7 linuxea.node-1.com <none> dpment-linuxea-798ff6bc87-fgpcr 1/1 Running 0 15s 172.16.5.32 linuxea.node-3.com <none> dpment-linuxea-df4b6f749-5jlcb 1/1 Terminating 0 19m 172.16.3.4 linuxea.node-1.com <none> dpment-linuxea-df4b6f749-rzndk 1/1 Terminating 0 19m 172.16.3.5 linuxea.node-1.com <none> dpment-linuxea-df4b6f749-wwpck 1/1 Terminating 0 19m 172.16.3.6 linuxea.node-1.com <none>那如果要调度到node2的污点上,改成NoExecute即可但是这样一来,就只有node2有污点的行为效果是NoExecute,而node1和node3没有,就只能调度到Node2了。 tolerations: - key: "node_type" operator: "Exists" value: "" effect: "NoExecute"而后apply[root@linuxea schedule]# kubectl apply -f demo.yaml deployment.apps/dpment-linuxea configured就都调度到node2上了。[root@linuxea schedule]# kubectl get pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-798ff6bc87-8kpw2 1/1 Terminating 0 14m 172.16.5.33 linuxea.node-3.com <none> dpment-linuxea-798ff6bc87-9fgn4 1/1 Terminating 0 14m 172.16.3.7 linuxea.node-1.com <none> dpment-linuxea-798ff6bc87-fgpcr 1/1 Terminating 0 14m 172.16.5.32 linuxea.node-3.com <none> dpment-linuxea-7b54d565c7-2md6h 1/1 Running 0 2s 172.16.4.31 linuxea.node-2.com <none> dpment-linuxea-7b54d565c7-5pmth 1/1 Running 0 3s 172.16.4.30 linuxea.node-2.com <none> dpment-linuxea-7b54d565c7-v6bdq 1/1 Running 0 5s 172.16.4.29 linuxea.node-2.com <none>那如果我想在三个节点都想被容忍,我们在修改下,将effect制空,如下: tolerations: - key: "node_type" operator: "Exists" value: "" effect: ""这样一来,value值为空,effect的容忍效果也为空,那就只有键生效,相同为node_type的键有node1,node2,node3三个node都符合。就会调度到三个节点上[root@linuxea schedule]# kubectl apply -f demo.yaml deployment.apps/dpment-linuxea configured[root@linuxea schedule]# kubectl get pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE dpment-linuxea-7748786749-4s2qv 1/1 Running 0 5s 172.16.4.32 linuxea.node-2.com <none> dpment-linuxea-7748786749-6llcz 1/1 Running 0 6s 172.16.5.34 linuxea.node-3.com <none> dpment-linuxea-7748786749-dv4nf 1/1 Running 0 4s 172.16.3.8 linuxea.node-1.com <none>
2018年12月02日
2,910 阅读
0 评论
0 点赞
1
2
3
4
...
8