摘要: 这是本系列的第2篇内容,将介绍在Docker和Kubernetes环境中解决遗留应用无法识别容器资源限制的问题。
本系列文章记录了企业客户在应用Kubernetes时的一些常见问题
这是本系列的第2篇内容,将介绍在Docker和Kubernetes环境中解决遗留应用无法识别容器资源限制的问题。
Linuxs利用Cgroup实现了对容器的资源限制,但在容器内部依然缺省挂载了宿主机上的procfs的/proc目录,其包含如:meminfo, cpuinfo,stat, uptime等资源信息。一些监控工具如free/top或遗留应用还依赖上述文件内容获取资源配置和使用情况。当它们在容器中运行时,就会把宿主机的资源状态读取出来,引起错误和不便。
LXCFS简介
LXCFS通过用户态文件系统,在容器中提供下列procfs 的文件。
/proc/cpuinfo /proc/diskstats /proc/meminfo /proc/stat /proc/swaps /proc/uptime
LXCFS的示意图如下
比如,把宿主机的 /var/lib/lxcfs/proc/memoinfo 文件挂载到Docker容器的/proc/meminfo位置后。容器中进程读取相应文件内容时,LXCFS的FUSE实现会从容器对应的Cgroup中读取正确的内存限制。从而使得应用获得正确的资源约束设定。
Docker环境下LXCFS使用
注:
- 本文采用CentOS 7.4作为测试环境,并已经开启FUSE模块支持。
- Docker for Mac/Minikube等开发环境由于采用高度剪裁过的操作系统,无法支持FUSE,并运行LXCFS进行测试。
安装 lxcfs 的RPM包
wget https://copr-be.cloud.fedoraproject.org/results/ganto/lxd/epel-7-x86_64/00486278-lxcfs/lxcfs-2.0.5-3.el7.centos.x86_64.rpm yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm
启动 lxcfs
lxcfs /var/lib/lxcfs &
测试
$docker run -it -m 256m \ -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \ -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \ -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \ -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \ -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \ -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \ ubuntu:16.04 /bin/bash root@f4a2a01e61cd:/# free total used free shared buff/cache available Mem: 262144 708 261436 2364 0 261436 Swap: 0 0 0
我们可以看到total的内存为256MB,配置已经生效。
lxcfs 的 Kubernetes实践
一些同学问过如何在Kubernetes集群环境中使用lxcfs,我们将给大家一个示例方法供参考。
首先我们要在集群节点上安装并启动lxcfs,我们将用Kubernetes的方式,用利用容器和DaemonSet方式来运行 lxcfs FUSE文件系统。
本文所有示例代码可以通过以下地址从Github上获得
git clone https://github.com/denverdino/lxcfs-initializer cd lxcfs-initializer
其manifest文件如下
apiVersion: apps/v1beta2 kind: DaemonSet metadata: name: lxcfs labels: app: lxcfs spec: selector: matchLabels: app: lxcfs template: metadata: labels: app: lxcfs spec: hostPID: true tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: lxcfs image: registry.cn-hangzhou.aliyuncs.com/denverdino/lxcfs:2.0.8 imagePullPolicy: Always securityContext: privileged: true volumeMounts: - name: rootfs mountPath: /host volumes: - name: rootfs hostPath: path: /
注: 由于 lxcfs FUSE需要共享系统的PID名空间以及需要特权模式,所有我们配置了相应的容器启动参数。
可以通过如下命令在所有集群节点上自动安装、部署完成 lxcfs,是不是很简单?:-)
kubectl create -f lxcfs-daemonset.yaml
那么如何在Kubernetes中使用 lxcfs 呢?和上文一样,我们可以在Pod的定义中添加对 /proc 下面文件的 volume(文件卷)和对 volumeMounts(文件卷挂载)定义。然而这就让K8S的应用部署文件变得比较复杂,有没有办法让系统自动完成相应文件的挂载呢?
其 manifest 文件如下
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: lxcfs-initializer-default namespace: default rules: - apiGroups: ["*"] resources: ["deployments"] verbs: ["initialize", "patch", "watch", "list"] --- apiVersion: v1 kind: ServiceAccount metadata: name: lxcfs-initializer-service-account namespace: default --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: lxcfs-initializer-role-binding subjects: - kind: ServiceAccount name: lxcfs-initializer-service-account namespace: default roleRef: kind: ClusterRole name: lxcfs-initializer-default apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1beta1 kind: Deployment metadata: initializers: pending: [] labels: app: lxcfs-initializer name: lxcfs-initializer spec: replicas: 1 template: metadata: labels: app: lxcfs-initializer name: lxcfs-initializer spec: serviceAccountName: lxcfs-initializer-service-account containers: - name: lxcfs-initializer image: registry.cn-hangzhou.aliyuncs.com/denverdino/lxcfs-initializer:0.0.2 imagePullPolicy: Always args: - "-annotation=initializer.kubernetes.io/lxcfs" - "-require-annotation=true" --- apiVersion: admissionregistration.k8s.io/v1alpha1 kind: InitializerConfiguration metadata: name: lxcfs.initializer initializers: - name: lxcfs.initializer.kubernetes.io rules: - apiGroups: - "*" apiVersions: - "*" resources: - deployments
注: 这是一个典型的 Initializer 部署描述,首先我们创建了service account lxcfs-initializer-service-account,并对其授权了 “deployments” 资源的查找、更改等权限。然后我们部署了一个名为 “lxcfs-initializer” 的Initializer,利用上述SA启动一个容器来处理对 “deployments” 资源的创建,如果deployment中包含 initializer.kubernetes.io/lxcfs为true的注释,就会对该应用中容器进行文件挂载
我们可以执行如下命令,部署完成之后就可以愉快地玩耍了
kubectl apply -f lxcfs-initializer.yaml
下面我们部署一个简单的Apache应用,为其分配256MB内存,并且声明了如下注释 “initializer.kubernetes.io/lxcfs”: “true”
其manifest文件如下
apiVersion: apps/v1beta1 kind: Deployment metadata: annotations: "initializer.kubernetes.io/lxcfs": "true" labels: app: web name: web spec: replicas: 1 template: metadata: labels: app: web name: web spec: containers: - name: web image: httpd:2 imagePullPolicy: Always resources: requests: memory: "256Mi" cpu: "500m" limits: memory: "256Mi" cpu: "500m"
我们可以用如下方式进行部署和测试
$ kubectl create -f web.yaml deployment "web" created $ kubectl get pod NAME READY STATUS RESTARTS AGE web-7f6bc6797c-rb9sk 1/1 Running 0 32s $ kubectl exec web-7f6bc6797c-rb9sk free total used free shared buffers cached Mem: 262144 2876 259268 2292 0 304 -/+ buffers/cache: 2572 259572 Swap: 0 0 0
我们可以看到free命令返回的 total memory 就是我们设置的容器资源容量。
我们可以检查上述Pod的配置,果然相关的 procfs 文件都已经挂载正确
$ kubectl describe pod web-7f6bc6797c-rb9sk ... Mounts: /proc/cpuinfo from lxcfs-proc-cpuinfo (rw) /proc/diskstats from lxcfs-proc-diskstats (rw) /proc/meminfo from lxcfs-proc-meminfo (rw) /proc/stat from lxcfs-proc-stat (rw) ...
总结
本文介绍了通过 lxcfs 提供容器资源可见性的方法,可以帮助一些遗留系统更好的识别容器运行时的资源限制。
同时,在本文中我们介绍了利用容器和DaemonSet的方式部署lxcfs FUSE,这不但极大简化了部署。也可以方便地利用Kubernetes自身的容器管理能力,支持lxcfs进程失效时自动恢复,在集群伸缩时也可以保证节点部署的一致性。这个技巧对于其他类似的监控或者系统扩展都是适用的。
另外我们介绍了利用Kubernetes的扩展机制 Initializer,实现对 lxcfs 文件的自动化挂载。整个过程对于应用部署人员是透明的,可以极大简化运维复杂度。同时利用类似的方法,我们可以灵活地定制应用部署的行为,满足业务的特殊要求。
阿里云Kubernetes服务 全球首批通过Kubernetes一致性认证,简化了Kubernetes集群生命周期管理,内置了与阿里云产品集成,也将进一步简化Kubernetes的开发者体验,帮助用户关注云端应用价值创新。
阅读更多干货好文,请关注扫描以下二维码:
相关推荐
Kubernetes群集联合教程 Kubernetes(简称K8s)是一种强大的开源容器编排系统,它使得部署、...通过深入学习和实践这个教程,你将能够熟练掌握如何有效地利用Kubernetes集群联合来提升你的容器化应用部署和管理效率。
在Kubernetes中,资源清单(Resource Manifest)是用于定义和管理集群中对象的YAML或JSON格式文件。这些对象可以是工作负载、服务、配置、存储等不同类型的资源。资源清单通常包含`apiVersion`、`kind`、`metadata`...
:locked: 很棒的Kubernetes安全 精选的Kubernetes安全资源的精选列表...组或用户的Kubernetes角色 -kubectl的深度Kubernetes可见性扫描Kubernetes容器,部署,守护程序和状态集显示谁有权使用<verb> <resource> kyverno
本书提供了一套完整的解决方案,利用Kubernetes的原生能力,并通过策略驱动的监控和执行来强化安全性,同时提供了集群、命名空间、节点、Pod和容器级别的运行时保护以及合规性控制。 Aqua Security公司提供了一系列...
然后,可以使用典型的Sentry功能(例如通知)来帮助操作和开发人员可见性。 在上创建一个新项目,并在启动sentry-kubernetes容器时使用您的DSN: kubectl run sentry-kubernetes \ --image getsentry/sentry-...
1. **性能**:容器轻量级,启动速度快,资源利用率高。 2. **可重复性**:容器确保了应用在任何环境中的一致行为。 3. **隔离性**:每个容器都有自己独立的运行环境,避免相互干扰。 4. **服务质量**:通过资源配额...
Kubernetes基础插件 该存储库包含引导所需的默认插件集。 概述 该存储库的结构遵循参考的,并使用的。 您将在此处找到以下目录: addons/ -包含插件资源的实际清单 metadata/ -包含addons/中addons/静态元数据 ...
PostgreSQL行可见性验证是数据库管理系统中的一个重要概念,它关系到数据库事务的一致性、隔离性以及并发控制。以下将详细介绍PostgreSQL中行可见性验证的相关知识点。 首先,了解事务ID(Transaction ID)和元组...
在这个实例中,我们将学习如何利用Silverlight来控制图层的可见性,具体是通过Checkbox控件来实现。 首先,我们需要了解Silverlight中的图层概念。在Silverlight应用程序中,图层通常指的是UI元素的层次结构。这些...
2. **多级剔除**:为了优化性能,可见性剔除通常分为多个层次。例如,可以先进行简单的 frustum culling(视锥体剔除),剔除完全在相机视锥体之外的对象;然后进行更精细的 occlusion culling,进一步确定哪些物体...
5. **Integrations**:Grafeas可以与其他工具和服务,如Trivy(一个开源的容器安全扫描器)、Docker、Kubernetes等进行集成,以实现端到端的容器安全解决方案。 在实际应用中,Grafeas可以帮助企业实现以下目标: ...
Grafeas是一个开放源代码项目,专注于提供软件容器的元数据,包括安全、合规性和版本信息,而Kubernetes则是目前最流行的容器编排系统。这两者的结合对于现代化的DevOps流程至关重要。下面,我们将通过一个详细的循...
1. **性能高效**:利用Golang的并发特性,GoKubernetes可以在不显著增加资源消耗的情况下提供高吞吐量的监控。 2. **可扩展性**:由于Golang的模块化设计,该工具可以轻松地与其他监控系统集成,如Prometheus或...
标题中的“电信设备-利用摄像机设备来实现可见光短距离通信的无线终端”揭示了本次讨论的主题,即一种利用摄像机设备进行可见光通信(Visible Light Communication, VLC)的无线通信技术。这是一种创新的方式,将...
7. **信息技术的应用**:在现代企业管理中,信息系统如ERP(企业资源规划)和CRM(客户关系管理)系统等,能够帮助收集、分析和共享需求信息,实现需求可见性的提升。 8. **供应链协同**:与供应商、分销商共享需求...
在游戏场景中,我们可以通过遮罩来实现部分区域的可见性控制,如在新手引导中,通常会遮盖部分界面,只展示关键的操作步骤。 制作新手引导界面的关键步骤如下: 1. **创建CCLayerColor**: 首先,我们需要创建一个...
在bridge网络中,每个容器都会分配一个唯一的IP地址,且默认情况下对外部网络是不可见的。如果你想让外部网络访问到某个容器,你需要使用`--publish`或`-p`选项暴露容器的端口。例如,`docker run -p 80:80 nginx`...
### 关于Kubernetes(K8s):开源容器编排平台的关键知识点 #### 一、容器化应用程序 Kubernetes(K8s)的核心价值在于它能够有效地管理容器化应用程序。容器化技术允许开发者将应用程序及其所有相关的依赖项打包...
描述中提到的“快速寻找外链资源的方法”是SEO从业者关注的重点,因为有效的外链建设能够快速提升网站的可见性和搜索引擎排名。 SEO外链,简单来说,就是从其他网站指向你的网站的链接。这些链接被搜索引擎视为对你...