从 k8s changelog 了解 k8s

本文从 k8s 的更新日志中了解 k8s 的变迁,,从版本跨度从1.2-1.10。GitHub 地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md

v1.0 - 201507

Google宣布成立CNCF基金会,Kubernetes 1.0正式发布。已投入生产的Kubernetes有着如下特性:

APP服务,网络,存储

  • 在生产环境中部署和管理工作负载,包括DNS、负载均衡、扩展、应用级别的健康检查和服务记录。
  • 与各种本地和网络卷的状态应用支持,如谷歌计算引擎永久磁盘,AWS弹性块存储和NFS。
  • 在pod中部署容器,pod与容器密切相关,支持简单更新和回滚。
  • 用命令执行检查和调试应用,通过CLI和UI进行端口转发,日志收集,资源监控。

集群管理

  • 实时升级以及扩展。
  • 通过命名空间分割集群,更深层次的管控资源。例如,你可以将集群细分给不同的应用或测试生产环境。

性能和稳定性

  • API响应速度快,平均容器调用时间小于5秒。
  • 扩展测试,每个集群中,容器1000秒,节点100秒。
  • 稳定的API

v1.1 - 201511

v1.2 - 201603

  1. 显著增加集群规模

    支撑的集群规模增加400%。单个节点性能提升四倍。

  2. 简化应用部署和管理

    1. Dynimic Configuration 功能(动态配置)。
    2. TurnKey Deployments 应用部署和滚动升级的自动化。
  3. 自动化集群管理

    1. 在同一个云平台上实现跨区扩展。一个Service下的Pod会自动扩展到其它可用区,从而做到跨区容错。
    2. 简化One-Pod-Per-Node应用的部署管理(通过Extensions API中的DaemonSet API实现)。Kubernetes的调度机制能够保证一个应用每个节点上运行同样的Pod,并且只运行一个,比如logging agent。
    3. 支持TLS和7层网络(通过Extensions API中的ingress API实现,目前为Beta版)。基于TLS和基于HTTP的七层网络路由,Kubernetes可以更方便地集成到传统的网络环境中。
    4. 支持Graceful Node Shutdown(及Node Drain)。新增的“kubelet drain”命令可以很优雅地将pod从某些节点驱逐出去,从而为节点维护做准备(比如升级kernel
    5. 支持自定义Autoscaling的指标(通过Autoscaling API中的HorizontalPodAutoscaler API实现)。Horizontal Pod Autoscaling支持自定义模版(目前为Alpha版),允许用户指定应用级别的指标和应用自动伸缩的阈值。
    6. 新的控制台(dashboard)具备与kubelet commandline类似的功能,允许用户通过一种新方式与kubernetes集群交互。

其它重要的改进

  • Job在v1.1中为Beta版,在1.2中可以投入生产环境。
  • Kube-Proxy默认采用基于iptables的方式。
  • 可以在kubelet中设置系统保留资源来提高Node节点的稳定性。参数为 –system-reserved 和 –kube-reserved。
  • Liveness和readiness探针支持更多的参数选项,包括periodSeconds、successThreshold和failureThreshold。
  • 新的ReplicaSet API(Extensions API中,目前处于Beta版)
  • 命令kubelet run默认产生Deployments(而不是ReplicationControllers)和Jobs(而不是Pods)对象。
  • Pods能够使用环境变量中的Secret数据,并将其作为commandline参数传递给container
  • 产生Heapster的稳定版,并支持最多1000个节点:更多的监控指标、减少延迟、减少CPU和内存消耗(大约4M每个节点)。

v1.3 - 201607

该版本包含的特性主要是为了实现两个用户愿望:

  • 一个是跨集群、区域和云边界部署服务;
  • 另一个是在容器中运行更为多样化的工作负载,包括有状态服务。

新特性:

  • 提升规模和自动化——允许用户根据应用程序需求自动向上和向下扩展他们的服务。简化集群的自动向上和向下扩展,并且将每个集群的最大节点数量提升至原来的两倍。

  • 有状态应用程序的alpha支持—— Kubernetes API新增了一个“PetSet”对象:

    • 多次重启也不会变化的永久性主机名;
    • 自动为每个容器配置永久性磁盘,可以在容器生命周期结束后继续存在;
    • 组内唯一标识,允许群集和群首选举;
    • 初始化容器,对启动集群应用程序至关重要。
  • 简化本地开发——引入了Minikube,只要一条命令,开发人员就可以在笔记本上启动一个本地Kubernetes集群,而且与一个完整Kubernetes集群的API兼容。

  • 支持rkt容器镜像和OCI&CNI 容器标准。

  • 更新dashboard UI。

v1.4 - 201609

  • 创建kubernetes集群只需要两条命令
  • 增强了对有状态应用的支持
  • 增加了集群联盟(Federation)API
    • 跨kubernetes集群均匀的调度任务负载
    • 将一个最便宜的kubernetes集群的工作负载进行最大化,如果超出了这个kubernetes集群的承受能力,那么将额外的工作负载路由到一个更昂贵的kubernetes集群中
    • 根据应用地理区域需求,调度工作负载到不同的kubernetes集群中,对于不同的终端用户,提供更高的带宽和更低的延迟。
  • 支持容器安全控制
  • 增强包括调度在内的Kubernetes基础架构
  • 通过Kubernetes DashBoard UI已经可以实现90%的命令行操作

v1.5 - 201612

1、API 机制

  • [beta] kube-apiserver支持OpenAPI从alpha移动到beta, 第一个non-go客户端是基于此特性。

2、应用

  • [Stable]当replica sets不能创建Pods时,它们将通过API报告失败的详细底层原因。
  • [Stable] kubectl apply现可通过–prune删除不再需要的资源
  • [beta] Deployments现可通过API升级到新版本,而之前是无法通过滚动来进行升级的
  • [beta] StatefulSets(原PetSet)允许要求持久化identity或单实例存储的工作负载从而在Kubernetes创建和管理。
  • [beta]为了提供安全保障,集群不会强行删除未响应节点上的Pods,如果用户通过CLI强行删除Pods会收到警告。

3、认证

  • [Alpha]改进了基于角色的访问控制alpha API。(包括一组默认的集群角色)
  • [Beta]添加了对Kubelet API访问的认证/授权机制。

4、AWS

  • [stable]角色出现在kubectl get nodes的结果里。

5、集群生命周期

  • [alpha] 提升了kubeadm二进制包的交互和可用性,从而更易于新建一个运行集群。

6、集群运维

  • [alpha] 在GCE上使用kube-up/kube-down脚本来创建/移除集群高可用(复制)的主节点。

7、联邦

  • [beta] 支持联邦ConfigMaps。
  • [alpha] 支持联邦Daemonsets。
  • [alpha] 支持联邦Deployments。
  • [alpha]集群联邦:为联邦资源添加对于DeleteOptions.OrphanDependents的支持。
  • [alpha]引入新命令行工具:kubefed,简化联邦控制台的部署以及集群注册/注销体验。

8、网络

  • [stable]服务可以通过DNS名称被其他服务引用,而不是只有在pods里才可以。
  • [beta]为NodePort类型和LoadBalancer的服务保留源IP的选项。
  • [stable]启用beta ConfigMap参数支持的DNS水平自动伸缩

9、节点

  • [alpha]支持在容器运行时启用用户命名空间重映射的时候,保留对宿主用户命名空间的访问。
  • [alpha]引入了v1alpha1版本的CRI(容器运行时接口) API,它允许可插拔的容器运行时;现有一个已经就绪的用于测试和反馈的docker-CRI集成。
  • [alpha]Kubelet基于QoS层在每个Pod的CGroup层级里启动容器。
  • [beta]Kubelet集成了memcg提示消息API,来检测是否超过阈值。
  • [beta]引入了Beta版本的容器化节点一致性测试: gcr.io/google_containers/node-test:0.2。从而让用户验证node设置。

10、调度

  • [alpha]添加了对不透明整数资源(node级)的审计支持。
  • [beta] PodDisruptionBudget已经升级到Beta版,当想要应用SLO时,可以用来安全地drain节点。

11、UI

  • [stable]Dashboard UI如今显示面向用户的对象及它们的资源使用情况。

12、Windows

  • [alpha]添加了对Windows Server 2016节点和调度Windows Server Container的支持。

v1.6 - 201703

  1. 扩大集群规模,加强集群联邦功能

    将Kubernetes底层架构预设改成etcd v3版本,可支持的集群规模也扩大至5,000个节点,可支持的Pod规模也增加到15万个

  2. 靠角色访问控制机制加强安全

    直接用API来取得不同账号的权限管理政策,来控制使用者账号或服务,可将系统资源指派给特定命名空间,让所属账号来存取。

  3. 储存动态分配

    PV PVC StorageClass

  4. 强化使用者对Pod的控制

    指定每个Pod一个节点标签(Node Label),限制Pod只能在特定节点中运行,也可以将Pod排除于特定节点上运作。

  5. 更新容器Runtime接口及常驻程序

v1.7 - 20170629

转自https://jimmysong.io/kubernetes-handbook/appendix/kubernetes-1.7-changelog.html

2017年6月29日,kuberentes1.7发布。该版本的kubernetes在安全性、存储和可扩展性方面有了很大的提升。改版本的详细更新文档请查看Changelog

这些新特性中包含了安全性更高的加密的secret、pod间通讯的网络策略,限制kubelet访问的节点授权程序以及客户端/服务器TLS证书轮换。

对于那些在Kubernetes上运行横向扩展数据库的人来说,这个版本有一个主要的特性,可以为StatefulSet添加自动更新并增强DaemonSet的更新。我们还宣布了对本地存储的Alpha支持,以及用于更快地缩放StatefulSets的突发模式。

此外,对于高级用户,此发行版中的API聚合允许使用用于自定义的API与API server同时运行。其他亮点包括支持可扩展的准入控制器,可插拔云供应商程序和容器运行时接口(CRI)增强功能。

新功能

安全

  • Network Policy API 提升为稳定版本。用户可以通过使用网络插件实现的网络策略来控制哪些Pod之间能够互相通信。
  • 节点授权和准入控制插件是新增加的功能,可以用于限制kubelet可以访问的secret、pod和其它基于节点的对象。
  • 加密的Secret和etcd中的其它资源,现在是alpha版本。
  • Kubelet TLS bootstrapping现在支持客户端和服务器端的证书轮换。
  • 由API server存储的审计日志现在更具可定制性和可扩展性,支持事件过滤和webhook。它们还为系统审计提供更丰富的数据。

有状态负载

  • StatefulSet更新是1.7版本的beta功能,它允许使用包括滚动更新在内的一系列更新策略自动更新诸如Kafka,Zookeeper和etcd等有状态应用程序。
  • StatefulSets现在还支持对不需要通过Pod管理策略进行排序的应用程序进行快速扩展和启动。这可以是主要的性能改进。
  • 本地存储(alpha)是有状态应用程序最常用的功能之一。用户现在可以通过标准的PVC/PV接口和StatefulSet中的StorageClass访问本地存储卷。
  • DaemonSet——为每个节点创建一个Pod,现在有了更新功能,在1.7中增加了智能回滚和历史记录功能。
  • 新的StorageOS Volume插件可以使用本地或附加节点存储中以提供高可用的集群范围的持久卷。

可扩展性

  • 运行时的API聚合是此版本中最强大的扩展功能,允许高级用户将Kubernetes风格的预先构建的第三方或用户创建的API添加到其集群中。
  • 容器运行时接口(CRI)已经增强,可以使用新的RPC调用从运行时检索容器度量。 CRI的验证测试已经发布,与containerd进行了Alpha集成,现在支持基本的生命周期和镜像管理。参考深入介绍CRI的文章。

其它功能

  • 引入了对外部准入控制器的Alpha支持,提供了两个选项,用于向API server添加自定义业务逻辑,以便在创建对象和验证策略时对其进行修改。
  • 基于策略的联合资源布局提供Alpha版本,用于根据自定义需求(如法规、定价或性能)为联合(federated)集群提供布局策略。

弃用

  • 第三方资源(TPR)已被自定义资源定义(Custom Resource Definitions,CRD)取代,后者提供了一个更清晰的API,并解决了TPR测试期间引发的问题和案例。如果您使用TPR测试版功能,则建议您迁移,因为它将在Kubernetes 1.8中被移除。

v1.8 - 20170928

2017年9月28日,kubernetes1.8版本发布。该版本中包括了一些功能改进和增强,并增加了项目的成熟度,将强了kubernetes的治理模式,这些都将有利于kubernetes项目的持续发展。

聚焦安全性

Kubernetes1.8的基于角色的访问控制(RBAC)成为stable支持。RBAC允许集群管理员动态定义角色对于Kubernetes API的访问策略。通过网络策略筛选出站流量的Beta支持,增强了对入站流量进行过滤的现有支持。 RBAC和网络策略是强化Kubernetes内组织和监管安全要求的两个强大工具。

Kubelet的传输层安全性(TLS)证书轮换成为beta版。自动证书轮换减轻了集群安全性运维的负担。

聚焦工作负载支持

Kubernetes 1.8通过apps/v1beta2组和版本推动核心工作负载API的beta版本。Beta版本包含当前版本的Deployment、DaemonSet、ReplicaSet和StatefulSet。 工作负载API是将现有工作负载迁移到Kubernetes以及开发基于Kubernetes的云原生应用程序提供了基石。

对于那些考虑在Kubernetes上运行大数据任务的,现在的工作负载API支持运行kubernetes原生支持的Apache Spark

批量工作负载,比如夜间ETL工作,将从CronJobs的beta版本中受益。

自定义资源定义(CRD)在Kubernetes 1.8中依然为测试版。CRD提供了一个强大的机制来扩展Kubernetes和用户定义的API对象。 CRD的一个用例是通过Operator Pattern自动执行复杂的有状态应用,例如键值存储、数据库和存储引擎。随着稳定性的继续推进,预计将继续加强对CRD的验证

更多

Volume快照、PV调整大小、自动taint、pod优先级、kubectl插件等!

v1.9 - 20171215

2017年12月15日,kubernetes1.9版本发布。Kubernetes依然按照每三个月一个大版本发布的速度稳定迭代,这是今年发布的第四个版本,也是今年的最后一个版本,该版本最大的改进是Apps Workloads API成为稳定版本,这消除了很多潜在用户对于该功能稳定性的担忧。还有一个重大更新,就是测试支持了Windows了,这打开了在kubernetes中运行Windows工作负载的大门。

  • Workloads API GA

    apps/v1 Workloads API成为GA(General Availability),且默认启用。 Apps Workloads API将DaemonSetDeploymentReplicaSetStatefulSet API组合在一起,作为Kubernetes中长时间运行的无状态和有状态工作负载的基础。

    Deployment和ReplicaSet是Kubernetes中最常用的两个对象,经过一年多的实际使用和反馈后,现在已经趋于稳定。SIG apps同时将这些经验应用到另外的两个对象上,使得DaemonSet和StatefulSet也能顺利毕业走向成熟。v1(GA)意味着已经生产可用,并保证长期的向后兼容。

  • Windows支持(beta)

    Kubernetes最初是为Linux系统开发的,但是用户逐渐意识到容器编排的好处,我们看到有人需要在Kubernetes上运行Windows工作负载。在12个月前,我们开始认真考虑在Kubernetes上支持Windows Server的工作。 SIG-Windows现在已经将这个功能推广到beta版本,这意味着我们可以评估它的使用情况

  • 增强存储

    kubernetes从第一个版本开始就支持多种持久化数据存储,包括常用的NFS或iSCSI,以及对主要公共云和私有云提供商的存储解决方案的原生支持。随着项目和生态系统的发展,Kubernetes的存储选择越来越多。然而,为新的存储系统添加volume插件一直是一个挑战。

    容器存储接口(CSI)是一个跨行业标准计划,旨在降低云原生存储开发的障碍并确保兼容性。 SIG-StorageCSI社区正在合作提供一个单一接口,用于配置、附着和挂载与Kubernetes兼容的存储。

    Kubernetes 1.9引入了容器存储接口(CSI)的alpha实现,这将使挂载新的volume插件就像部署一个pod一样简单,并且第三方存储提供商在开发他们的解决方案时也无需修改kubernetes的核心代码。

    由于该功能在1.9版本中为alpha,因此必须明确启用该功能,不建议用于生产使用,但它为更具扩展性和基于标准的Kubernetes存储生态系统提供了清晰的路线图。

  • 其它功能

    自定义资源定义(CRD)校验,现在已经成为beta,默认情况下已启用,可以用来帮助CRD作者对于无效对象定义给出清晰和即时的反馈。

    SIG Node硬件加速器转向alpha,启用GPU,从而实现机器学习和其他高性能工作负载。

    CoreDNS alpha可以使用标准工具来安装CoreDNS。

    kube-proxy的IPVS模式进入beta版,为大型集群提供更好的可扩展性和性能。

    社区中的每个特别兴趣小组(SIG)继续提供其所在领域的用户最迫切需要的功能。有关完整列表,请访问发行说明

v1.10 - 20180326

2018年3月26日,kubernetes1.10版本发布,这是2018年发布的第一个版本。该版本的Kubernetes主要提升了Kubernetes的成熟度、可扩展性与可插入性。

该版本提升了三大关键性功能的稳定度,分别为存储、安全与网络。另外,此次新版本还引入了外部kubectl凭证提供程序(处于alpha测试阶段)、在安装时将默认的DNS服务切换为CoreDNS(beta测试阶段)以及容器存储接口(简称CSI)与持久化本地卷的beta测试版。

下面再分别说下三大关键更新。

  • 存储
    • CSI(容器存储接口)迎来Beta版本,可以通过插件的形式安装存储。
    • 持久化本地存储管理也迎来Beta版本。
    • 对PV的一系列更新,可以自动阻止Pod正在使用的PVC的删除,阻止已绑定到PVC的PV的删除操作,这样可以保证所有存储对象可以按照正确的顺序被删除。
  • 安全
    • kubectl可以对接不同的凭证提供程序
    • 各云服务供应商、厂商以及其他平台开发者现在能够发布二进制插件以处理特定云供应商IAM服务的身价验证
  • 网络
    • 将原来的kube-dns切换为CoreDNS

kubernetes 创建 charts 的示例

本文记录将 eclipse 的物联网开源应用 kapua 容器化为 kubernetes charts 的要点。 项目demo也在我的github上面:kelvinblood/kapua-kubernetes

一 docker-compose

首先我们在官网上 https://www.eclipse.org/kapua/getting-started.php 看到 kapua 的启动命令:

$ docker run -td --name kapua-sql -p 8181:8181 -p 3306:3306 kapua/kapua-sql:0.3.2

$ docker run -td --name kapua-elasticsearch -p 9200:9200 -p 9300:9300 elasticsearch:5.4.0 -Ecluster.name=kapua-datastore -Ediscovery.type=single-node -Etransport.host=_site_ -Etransport.ping_schedule=-1 -Etransport.tcp.connect_timeout=30s

$ docker run -td --name kapua-broker --link kapua-sql:db --link kapua-elasticsearch:es --env commons.db.schema.update=true -p 1883:1883 -p 61614:61614 kapua/kapua-broker:0.3.2

$ docker run -td --name kapua-console --link kapua-sql:db --link kapua-broker:broker --link kapua-elasticsearch:es --env commons.db.schema.update=true -p 8080:8080 kapua/kapua-console:0.3.2

$ docker run -td --name kapua-api --link kapua-sql:db --link kapua-broker:broker --link kapua-elasticsearch:es --env commons.db.schema.update=true -p 8081:8080 kapua/kapua-api:0.3.2

在这里可以看到 kapua 一共分成五个组件:

  • sql
  • es
  • broker
  • console
  • api

我们先将这几个命令行组合起了成为一个 docker-compose 文件,便于管理:

version: '2'
services:
  kapua-sql:
    image: iot/kapua-sql:0.3.2
    restart: always

  kapua-elasticsearch:
    image: elasticsearch:5.4.0
    restart: always
    command:
    - -Ecluster.name=kapua-datastore
    - -Ediscovery.type=single-node
    - -Etransport.host=_site_
    - -Etransport.ping_schedule=-1
    - -Etransport.tcp.connect_timeout=30s

  kapua-broker:
    image: iot/kapua-broker:0.3.2
    restart: always
    links:
      - kapua-sql:db
      - kapua-elasticsearch:es
    environment:
      - commons.db.schema.update=true
      - DB_PORT_3306_TCP_PORT=3306
    ports:
      - "1883:1883"
      - "61614:61614"

  kapua-console:
    image: iot/kapua-console:0.3.2
    restart: always
    links:
      - kapua-sql:db
      - kapua-elasticsearch:es
      - kapua-broker:broker
    environment:
      - commons.db.schema.update=true
    ports:
      - "8080:8080"

  kapua-api:
    image: iot/kapua-api:0.3.2
    restart: always
    links:
      - kapua-sql:db
      - kapua-elasticsearch:es
      - kapua-broker:broker
    environment:
      - commons.db.schema.update=true
    ports:
      - "8080:8080"

有了这个文件,在单机上我们可以直接使用 docker-compose up -d 部署应用。


kubernetes 无法添加节点

今天在新增kubernetes节点时,发现无法新增节点,这篇文章记录下解决的情况。

新增节点

k8s新增节点时通过 token 验证,并带上ca证书的ha值。默认token的有效期为24小时。

# 重新生成新的token
kubeadm token create
kubeadm token list

# 获取ca证书sha256编码hash值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

# 节点加入集群
kubeadm join 172.10.1.100:6443 --token xxx --discovery-token-ca-cert-hash sha256:xxx --ignore-preflight-errors Swap

遇到问题

因为已经安装过好几次,只有这一次有问题,故而发现了本次安装不一样的地方:

在获取ca证书的hash值时,这次出现了这样的输出:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der> /dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
writing RSA key

最后一行命令添加节点时输出如下:

[discovery] Trying to connect to API Server "10.128.0.4:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.128.0.4:6443"
[discovery] Failed to connect to API Server "10.128.0.4:6443": cluster CA found in cluster-info configmap is invalid: public key sha256:9b263f52d90b62458a6a6c6.......02ddc34bf26e1ac not pinned

提示直接给出了另一个hash值。

解决问题

一个非常简单的方式解决:

将错误提示的hash值代替原先获得的hash值即可。

按常理来说,是不应该出现这样的问题的。显而易见是第二步获取hash值出了问题。对比以前使用的命令行,一下就找出了原因:

文档经过多次复制粘贴,命令行已经不完整了。参考官方文档https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-join/中的命令,重新运行得到正确的命令行:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

参考资料


防止容器因 jvm 占用资源过多被杀死而频繁重启

本文记录 jvm 和 elasticsearch 在容器中的设置要点。

JVM

不完全翻译自https://blog.csanchez.org/2017/05/31/running-a-jvm-in-a-container-without-getting-killed/

JDK 8u131 在 JDK 9 中有一个特性,可以在 Docker 容器运行时能够检测到多少内存的能力,这个功能在我看来,颇为流氓。

在容器内部运行 JVM,它在大多数情况下将如何默认最大堆为主机内存的1/4,而非容器内存的1/4。如果对 Java 容器中的jvm虚拟机不做任何限制,当我们同时运行几个 java 容器时,很容易导致服务器的内存耗尽、负载飙升而宕机;而如果我们对容器直接进行限制,就会导致内核在某个时候杀死 jvm 容器而导致频繁重启。

例如:

$ docker run -m 100MB openjdk:8u121 java -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 444.50M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

下面我们尝试 JDK 8u131 中的实验性参数 -XX:+UseCGroupMemoryLimitForHeap

$ docker run -m 100MB openjdk:8u131 java \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+UseCGroupMemoryLimitForHeap \
  -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 44.50M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

JVM能够检测容器只有100MB,并将最大堆设置为44M。

下面尝试一个更大的容器

$ docker run -m 1GB openjdk:8u131 java \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+UseCGroupMemoryLimitForHeap \
  -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 228.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

嗯,现在容器有1GB,但JVM仅使用228M作为最大堆。

除了JVM正在容器中运行以外,我们是否还可以优化它呢?

$ docker run -m 1GB openjdk:8u131 java \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+UseCGroupMemoryLimitForHeap \
  -XX:MaxRAMFraction=1 -XshowSettings:vm -version
VM settings:
    Max. Heap Size (Estimated): 910.50M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

使用-XX:MaxRAMFraction 我们告诉JVM使用可用内存/ MaxRAMFraction作为最大堆。使用-XX:MaxRAMFraction=1我们几乎所有可用的内存作为最大堆。

elasticsearch

不完全翻译自https://www.elastic.co/guide/en/elasticsearch/reference/5.4/heap-size.html

Elasticsearch 将通过Xms(最小堆大小)和Xmx(最大堆大小)设置来分配 jvm.options 指定的整个堆,默认使用最小和最大大小为2 GB的堆。这些设置的值取决于服务器上可用的内存。在生产环境时,要确保 Elasticsearch 有足够的可用堆。

一些好的经验是:

  • 将最小堆大小(Xms)和最大堆大小(Xmx)设置为彼此相等。

  • Elasticsearch 可用的堆越多,可用于缓存的内存就越多。但太多的堆会导致一直进行垃圾回收。

  • 将 Xmx 设置为不超过物理内存的50%,以确保有足够的物理内存留给内核文件系统缓存。

  • 不要将 Xmx 设置为J VM 用于压缩对象指针(压缩oops)的临界值以上,接近32 GB。可以通过在日志中查找一行来验证您是否处于限制之下,如下所示:

    heap size [1.9gb], compressed ordinary object pointers [true]
    
  • Even better, try to stay below the threshold for zero-based compressed oops; the exact cutoff varies but 26 GB is safe on most systems, but can be as large as 30 GB on some systems. You can verify that you are under the limit by starting Elasticsearch with the JVM options -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompressedOopsMode and looking for a line like the following:

    heap address: 0x000000011be00000, size: 27648 MB, zero based Compressed Oops
    

    showing that zero-based compressed oops are enabled instead of

    heap address: 0x0000000118400000, size: 28672 MB, Compressed Oops with base: 0x00000001183ff000
    

以下是如何通过jvm.options文件设置堆大小的示例:

-Xms2g 
-Xmx2g 

也可以通过环境变量设置堆大小。

ES_JAVA_OPTS ="- Xms2g -Xmx2g"./bin/elasticsearch 
ES_JAVA_OPTS ="- Xms4000m -Xmx4000m"./bin/elasticsearch 

参考资料


Linux:集群工具ClusterShell

ClusterShell 是一个轻量级的运维工具,可以在一台机器上向多台机器发送指令,轻松实现类似《黑客帝国》中批量关闭电厂的效果:

ClusterShell每天在Linux超级计算机(拥有超过5000个计算节点)上使用。使用很简单,只要在主控机上配置好子节点的ssh密钥登陆,同时做好节点配置即可,非常便捷。这篇文章介绍它的安装和简单使用。

安装

yum install -y clustershell
// or
apt-get install clustershell

配置

在/etc/clustershell目录下,手动创建groups文件

$ vim /etc/clustershell/groups

all: a1 host1 host2
name:host3 host4
adm: example0
oss: example4 example5
mds: example6
io: example[4-6]
compute: example[32-159]
gpu: example[156-159]
hadoop: z[1-4]

# 需要注意的是all 是必须配置的。

hadoop: z[1-4],是指定hadoop组中有四个节点,分别是z1,z2,z3,z4。

其它的配置也类似,可以加入多个组,使用的时候通过-g hadoop来选择。

命令

clush -a 全部 等于 clush -g all
clush -g 指定组
clush -w 操作主机名字,多个主机之间用逗号隔开
clush -g 组名 -c  --dest 文件群发     (-c等于--copy)

注意:clush 是不支持环境变量的 $PATH

实例

输出所有节点的信息

$ clush -a "uptime"
$ clush -b -a "uptime"

删除指定节点的文件

$ clush -w z2,z3,z4 rm -rf /mnt/zhao/soft/jdk

集群分发文件

$ clush -b -g hadoop --copy /mnt/zhao/package/jdk-7u79-linux-x64.tar.gz --dest /mnt/zhao/package/

集群查看文件

查看所有hadoop组中/mnt/zhao/package/目录下的文件,输出结果合并。

$ clush -b -g hadoop ls /mnt/zhao/package/

交互模式

启动clush,后面不带命令,就进入交互模式:

$ clush -w hadoop

参考资料