原理
在Kubernetes中,initContainer
通过挂载 emptyDir
卷(或其他类型的卷,但 emptyDir
是最常用的之一,因为它简单且易于理解),可以将其镜像中的文件复制到该卷中。由于 emptyDir
卷的生命周期与Pod相同,并且会被挂载到Pod内的所有容器中,因此当主容器挂载同名的 emptyDir
卷时,它就可以访问到 initContainer
复制到该卷中的文件了。
这种机制允许在Pod的启动阶段进行初始化操作,比如配置文件的复制、依赖的安装、权限的设置等,而无需在主容器的镜像中预先包含这些文件或执行这些操作。这样可以使得主容器的镜像更加轻量级和专注于运行应用程序本身。
下面是一个简化的过程描述:
- Pod被创建时,Kubernetes会首先检查是否有
initContainer
需要运行。 - 对于每个
initContainer
,Kubernetes会为其分配必要的资源,并挂载指定的卷(包括emptyDir
卷)。 initContainer
执行其指定的命令和参数,比如将文件从镜像内部复制到emptyDir
卷中。- 一旦
initContainer
成功完成其任务(即退出状态码为0),Kubernetes就会继续处理Pod中的下一个initContainer
(如果有的话),或者如果没有更多的initContainer
,则启动主容器。 - 主容器启动时,也会挂载相同的
emptyDir
卷(或其他指定的卷)。由于emptyDir
卷在Pod的生命周期内是持久的,并且会被所有容器共享,因此主容器可以通过其挂载的路径访问到initContainer
复制到该卷中的文件。
实操
了解了以上原理,要实现将skywalking无损接入部署在K8S的应用中,需要进行一下操作:
- 使用skywalking agent镜像作为initContainer
- initContainer挂载emptyDir(名称 skywalking 路径 /agent)将skyawalking agent代码复制到挂载的指定卷中(/agent)。
- 主容器中挂载相同emptyDir卷(名称 skywalking 路径/skywalking 这个是挂载路径可以与initContainer中不同,此时访问主容器中的/skywalking目录下文件实际上就是访问initContainer复制到/agent中的文件)
- 主容器配置相应的环境变量与启动参数。
YAML修改
initContainer对应yaml(仅修改部分)
initContainers:
- args:
- '-c'
- cp -R /skywalking/agent /agent/
command:
- /bin/sh
image: 'registry.xxx.com/xxx/skywalking:8.7.0-alpine'
imagePullPolicy: IfNotPresent
name: dataease-1
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /agent
name: skywalking-agent
volumes:
- emptyDir: {}
name: skywalking-agent
主容器
containers:
- env:
- name: JAVA_OPTIONS
value: >-
-Dfile.encoding=utf-8 -Xmx10240m -XX:MaxPermSize=1024m -Xss10m
-javaagent:/skywalking/agent/skywalking-agent.jar
- name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
value: >-
skywalking-skywalking.svc.cluster.local:11800
- name: SW_AGENT_NAME
value: 'test::test'
image: 'aaa.bbb.com/test:latest'
imagePullPolicy: IfNotPresent
name: dataease
ports:
- containerPort: 8080
name: tcp
protocol: TCP
resources:
limits:
cpu: '1'
memory: 4Gi
requests:
cpu: '1'
memory: 4Gi
volumeMounts:
- mountPath: /skywalking
name: skywalking-agent
上文中
SW_AGENT_COLLECTOR_BACKEND_SERVICES 为skywalking的服务端地址
SW_AGENT_NAME 为注册到skywalking的服务名称
在JAVA_OPTION中添加 javaagent:/skywalking/agent/skywalking-agent.jar指定skywalking包。
修改后,重启即可