SkyWalking探针在 k8s 中集成

1,631 阅读2分钟

最近公司需要在 k8s 环境接入 SkyWalking,要让应用无感知接入。

开始打算的是把agent文件放到基础镜像中,这样应用只需要引用包含agent的基础镜像即可。但是这样会有几个问题,首先不好管理agent,升级需要应用重新打镜像部署,动静太大。第二,不是所有应用都需要接入,要按需引入不同基础镜像,这样就多个一个步骤,应用会有感知。

最终我们使用的是通过initContainers的方式集成,跟helm搭配起来,只需要修改参数配置,就可以控制集成、移除agent。完整方案如下:

一、构建初始化镜像

把agent文件放进镜像中,并进行配置。升级agent只需要更换agent.zip然后重新打镜像即可。

FROM alpine:3.9.4
 
# 设置变量
ENV APP_HOME=/home \
    VERSION=8.3.0
 
# 增加用户和用户组
ARG USER=appl
ARG USER_GROUP=appl
RUN addgroup -g 1500 $USER_GROUP && \
    adduser -D -u 1500 $USER -G $USER_GROUP
 
# 切换用户安装
USER root
 
# 切换到应用目录
WORKDIR ${APP_HOME}
 
# 复制探针文件和可选插件到镜像
COPY agent.zip apm-aliyun-ons-1.x-plugin-2.1.0.jar apm-oracle-10.x-plugin-2.1.0.jar ./
 
# 安装探针
RUN unzip agent.zip && \
    rm agent.zip && \
    mv apm-aliyun-ons-1.x-plugin-2.1.0.jar apm-oracle-10.x-plugin-2.1.0.jar agent/plugins && \
    echo -e "\nplugin.springmvc.collect_http_params=true\nplugin.tomcat.collect_http_params=true\nplugin.http.http_params_length_threshold=2048\nplugin.mysql.trace_sql_parameters=true\n" >> agent/config/agent.config && \
    cp agent/optional-plugins/apm-trace-ignore-plugin-${VERSION}.jar agent/plugins && \
    touch agent/config/apm-trace-ignore-plugin.config && \
    echo "trace.ignore_path=\${SW_AGENT_TRACE_IGNORE_PATH:com.alibaba.dubbo.monitor.MonitorService.collect(URL),/healthCheck,/**/healthCheck,/**/actuator/**,/sba/**}" >> agent/config/apm-trace-ignore-plugin.config && \
    chown -R appl:appl ${APP_HOME}
 
USER appl

二、values.yaml增加相关配置

可以通过配置skywalking.enabled参数来启用和停用。

skywalking:
  enabled: true
  backendService: "sw-oap.dev:11800"
  init:
    pullPolicy: IfNotPresent
    repository: harbor-dev.k8s.com/skywalking-agent-init
    tag: 1.0.0
    resources:
      limits:
        cpu: 250m
        memory: 500Mi
      requests:
        cpu: 200m
        memory: 200Mi

三、添加jvm参数

agent需要jvm参数中配置javaagent才能生效,根据自己charts模板添加到合适的位置。

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "application.name" . }}-jvm-configmap
  namespace: {{ .Values.namespace }}
  labels:
{{ include "application.labels" . | indent 4 }}
data:
{{- (.Files.Glob "files/jvm.conf").AsConfig| nindent 2 }}
# 把探针配置加到 JAVA_OPTS 中
{{- if .Values.skywalking.enabled }}
{{ printf "JAVA_OPTS=\"$JAVA_OPTS -javaagent:%s/agent/skywalking-agent.jar\"" .Values.appHome | indent 4 }}
{{- end }}

四、修改 deployment.yml 文件

使用initContainers将agent文件复制到主容器中

{{- $appHome := .Values.appHome -}}
{{- $appName := .Values.appName -}}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "application.name" . }}
  namespace: {{ .Values.namespace }}
  labels:
{{ include "application.labels" . | indent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "application.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
      app: {{ include "application.name" . }}
  template:
    metadata:
      labels:
{{ include "application.labels" . | indent 8 }}
    spec:
# 初始化容器,复制探针文件到共享目录
{{- if .Values.skywalking.enabled }}
      initContainers:
        - name: init-agent
          image: "{{ .Values.skywalking.init.repository }}:{{ .Values.skywalking.init.tag }}"
          imagePullPolicy: {{ .Values.skywalking.init.pullPolicy }}
          command: [ 'sh', '-c', "mkdir -p {{ printf "%s/%s" .Values.appHome "agent" }} && cp -r /home/agent/* {{ printf "%s/%s" .Values.appHome "agent" }}" ]
          resources:
            {{- toYaml .Values.skywalking.init.resources | nindent 12 }}
          volumeMounts:
            - name: agent-dir
              mountPath: {{ printf "%s/%s" .Values.appHome "agent" }}
{{- end }}
      containers:
      - name: {{ include "application.name" . }}
        image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}/{{ .Values.appName }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        resources:
{{- if .Values.resources.requests }}
          requests:
            memory: {{ .Values.resources.requests.memory | quote }}
            cpu: {{ .Values.resources.requests.cpu | quote }}
{{- end }}
          limits:
            memory: {{ .Values.resources.limits.memory | quote }}
            cpu: {{ .Values.resources.limits.cpu | quote }}
        ports:
{{- range $index, $service := .Values.service }}
        - name: {{ $service.name }}
          containerPort: {{ $service.port }}
          protocol: TCP
{{- end }}
{{- if .Values.livenessProbe.enabled }}
        livenessProbe:
          httpGet:
            path: {{ .Values.appUri }}{{ .Values.livenessProbe.path }}
  {{- range $index, $service := .Values.service }}
    {{- if eq $service.name "http" }}
            port: {{ $service.port }}
    {{- end }}
  {{- end }}
          initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.livenessProbe.successThreshold }}
          periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
{{- end }}
{{- if .Values.readinessProbe.enabled }}
        readinessProbe:
          httpGet:
            path: {{ .Values.appUri }}{{ .Values.readinessProbe.path }}
  {{- range $index, $service := .Values.service }}
    {{- if eq $service.name "http" }}
            port: {{ $service.port }}
    {{- end }}
  {{- end }}
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
          timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }}
          successThreshold: {{ .Values.readinessProbe.successThreshold }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
{{- end }}
        volumeMounts:
        - name: {{ include "application.name" . }}-log
          mountPath: "{{ .Values.appHome }}/log"
        - name: {{ include "application.name" . }}-jvm-configmap
          mountPath: "{{ .Values.appHome }}/jvm .conf"
          subPath: jvm.conf
# 挂载卷,引入探针文件
{{- if .Values.skywalking.enabled }}
        - name: agent-dir
          mountPath: {{ printf "%s/%s" .Values.appHome "agent" }}
{{- end }}
# 环境变量,用来设置探针所需参数
{{- if .Values.skywalking.enabled }}
        env:
        - name: SW_AGENT_NAME
          value: {{ include "application.name" . }}
        - name: SW_LOGGING_DIR
          value: {{ printf "%s/%s" .Values.appHome "log" }}
        - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
          value: {{ .Values.skywalking.backendService }}
{{- end }}
      volumes:
      - name: {{ include "application.name" . }}-log
        persistentVolumeClaim:
          claimName: {{ include "application.name" . }}-pvc-log
{{- if (.Files.Glob "files/app.conf") }}
      - name: {{ include "application.name" . }}-jvm-configmap
        configMap:
          name: {{ include "application.name" . }}-jvm-configmap
          items:
            - key: jvm.conf
              path: jvm.conf
{{- end }}
# 声明卷
{{- if .Values.skywalking.enabled }}
      - name: agent-dir
        emptyDir: {}
{{- end }}
      securityContext:
        runAsUser: {{ .Values.storage.securityContext.runAsUser }}
        fsGroup: {{ .Values.storage.securityContext.fsGroup }}