InitContainer初始化容器和SideCar容器的作用和区别?

無名 发表于: 2021-07-27   最后更新时间: 2021-07-27 22:53:14   3,064 游览

InitContainer初始化容器和SideCar容器的作用和区别?

发表于 2021-07-27

init container初始化容器

在pod前的准备工作中使用Init Containers

k8s除了提供多容器外还提供了一种叫做初始化容器的功能,顾名思义它就是在pods 容器启动前工作的容器,一般场景中init containers这些容器在执行完后就不再运行了处于pause状态,这里特别要注意的是它的执行会严格按照编排的从上至下的顺序逐一初始化,这种顺序也是实现初始化工作不可缺少的。

下面以ES为例子详细说明一下其作用:

ES文档中建议生产中设置vm.max_map_count这个sysctl属性。

这就带来了一个问题,这个属性只能在节点级别才可以被修改,容器级别是没有做到隔离。

所以在不修改k8s代码的情况下你不得不使用特权级别来运行es已达到修改的目的,而这也不是你所希望的,

因为他会带来很严重的安全问题。

那么使用Init Containers就可以很好地解决这个问题,做法就是只在初始化容器中提权修改设置,那么后面的es只是普通容器就可以运行。如下:

apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: elasticsearch
 spec:
   selector:
     matchLabels:
       app.kubernetes.io/name: elasticsearch
   template:
     metadata:
       labels:
         app.kubernetes.io/name: elasticsearch
     spec:
       initContainers:
         - name: update-sysctl
           image: alpine:3.12
           command: ['/bin/sh']
           args:
             - -c
             - |
               sysctl -w vm.max_map_count=262144
           securityContext:
             privileged: true
       containers:
         - name: elasticsearch
           image: elasticsearch:7.9.3
           env:
             - name: discovery.type
               value: single-node
           ports:
             - name: http
               containerPort: 9200

除了上面这种常见的做法外初始化容器还可以这么用,当你HashicCorp Vault 来管理secrets而不是k8s secrets时,你可以在初始化容器中读取并放入一个emptyDir中。比如这样:

apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: myapp
   labels:
     app.kubernetes.io/name: myapp
 spec:
   selector:
     matchLabels:
       app.kubernetes.io/name: myapp
   template:
     metadata:
       labels:
         app.kubernetes.io/name: myapp
     spec:
       initContainers:
         - name: get-secret
           image: vault
           volumeMounts:
             - name: secrets
               mountPath: /secrets
           command: ['/bin/sh']
           args:
             - -c
             - |
               vault read secret/my-secret > /secrets/my-secret
       containers:
         - name: myapp
           image: myapp
           volumeMounts:
             - name: secrets
               mountPath: /secrets
       volumes:
         - name: secrets
           emptyDir: {}

更多的初始化容器应用场景

  • 在运行app前跑数据库的迁移脚本
  • 从外部读取/拉取一个超大文件时可以避免容器臃肿

Sidecar

边车模式,我一直把他想想成老式三轮摩托车的副座,它始终与摩托车主题保持一致并提供各种辅助功能,实现方式也是添加容器来增强pod中应用,边车最经典的应用就是日志跟踪。

在容器化的环境中最标准的做法是标准输出日志到一个中心化的收集器中用于分析和管理。但是很多老的应用是将日志写入文件,而更改日志输出有时候是一件困难的事。

那么添加一个日志跟踪的边车就意味着你可能不必去更改日志代码。回到ElasticSearch这个例子,虽然它默认是标准输出把它写入文件有点做作,这里作为示例我们可以这样部署:

apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: elasticsearch
   labels:
     app.kubernetes.io/name: elasticsearch
 spec:
   selector:
     matchLabels:
       app.kubernetes.io/name: elasticsearch
   template:
     metadata:
       labels:
         app.kubernetes.io/name: elasticsearch
     spec:
       containers:
         - name: elasticsearch
           image: elasticsearch:7.9.3
           env:
             - name: discovery.type
               value: single-node
             - name: path.logs
               value: /var/log/elasticsearch
           volumeMounts:
             - name: logs
               mountPath: /var/log/elasticsearch
             - name: logging-config
               mountPath: /usr/share/elasticsearch/config/log4j2.properties
               subPath: log4j2.properties
               readOnly: true
           ports:
             - name: http
               containerPort: 9200
         - name: logs
           image: alpine:3.12
           command:
             - tail
             - -f
             - /logs/docker-cluster_server.json
           volumeMounts:
             - name: logs
               mountPath: /logs
               readOnly: true
       volumes:
         - name: logging-config
           configMap:
             name: elasticsearch-logging
         - name: logs
           emptyDir: {}

这里的logs容器就是sidecar的一个具体实现,现实中可以使用具体的日志收集器代替比如filebeat。当app持续写入数据时,边车中的日志收集程序会不断的以只读的形式收集日志,这里的logs边车就把写入文件的logs变为标准输出而不需要修改任何代码。

其他边车模式常用的场景

  • 实时的重启ConfigMaps而不需要重启pod
  • 从Hashcorp Vault注入秘钥
  • 添加一个本地的redis作为一个低延迟的内存缓存服务

总结:

init Container:提前做准备的
sideCar:提供各种辅助功能

初始化容器(Init Containers)和 Sidecar 容器是 Kubernetes 中两种不同类型的容器,它们的作用和用途也不同。

初始化容器是在应用容器启动之前运行的一个特殊容器,它的作用是在应用容器启动前完成一些初始化操作。这些初始化操作可能包括数据准备、配置加载、数据库迁移、证书生成等等。当初始化容器完成任务后,它会自动退出,然后应用容器才会开始启动。初始化容器可以确保应用容器运行前所需要的依赖和配置已经准备就绪,从而提高了应用容器的可靠性。

相比之下,Sidecar 容器则是在应用容器运行期间一直存在的容器。它通常是用来提供一些额外的功能或者服务,比如日志收集、监控、安全认证等。在一个 Pod 中,多个容器可以共享同一个网络命名空间、存储卷等资源,这使得 Sidecar 容器能够很方便地与应用容器进行通信和交互。

因此,初始化容器和 Sidecar 容器在 Kubernetes 中的作用是不同的,前者用来做一些应用容器启动前的初始化操作,而后者则提供额外的功能或服务。需要根据具体的场景来选择使用哪一种容器。

你的答案

查看kubernetes相关的其他问题或提一个您自己的问题