These days, the company needs to connect SkyWalking to the K8S environment, so that the app has no perceptional access.

The initial intention is to put the Agent files in the base image so that the application only needs to reference the base image containing the Agent. However, there are several problems in this way. First, it is difficult to manage the Agent. The upgrade requires the application to deploy the image again, which is too noisy. Second, not all applications need access, and different base images need to be introduced as needed, so that the application will be aware of one more step.

Finally, we use the method of initContainers integration, with helm, only need to modify the parameter configuration, can control the integration and remove the agent. The complete scheme is as follows:

Build the initialization image

Put the Agent file into the image and configure it. To upgrade the Agent, replace agent.zip and re-mirror the agent.

FROM Alpine: 3.9.4
 
# set variable
ENV APP_HOME=/home \
    VERSION = 8.3.0
 
Add users and user groups
ARG USER=appl
ARG USER_GROUP=appl
RUN addgroup -g 1500 $USER_GROUP && \
    adduser -D -u 1500 $USER -G $USER_GROUP
 
# Switch user installation
USER root
 
# Switch to the app directory
WORKDIR ${APP_HOME}
 
Copy probe files and optional plug-ins to the image
COPY agent.zip Apm - aliyun - ons - 1 x - the plugin - 2.1.0. Jar Apm - oracle - 10. X - the plugin - 2.1.0. Jar . /
 
# Install probe
RUN unzip agent.zip && \
    rm agent.zip && \
    mv Apm - aliyun - ons - 1 x - the plugin - 2.1.0. Jar Apm - oracle - 10. X - the 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_thr eshold=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
Copy the code

Values. Yaml Add related configuration

You can enable and disable skywalking.enabled by configuring the parameter.

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
Copy the code

Add JVM parameters

Agent can take effect only when JavaAgent is configured in JVM parameters and added to the appropriate position according to its own Charts template.

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 }}
Add probe configuration to JAVA_OPTS
{{- if .Values.skywalking.enabled }}
{{ printf "JAVA_OPTS=\"$JAVA_OPTS -javaagent:%s/agent/skywalking-agent.jar\"" .Values.appHome | indent 4 }}
{{- end }}
Copy the code

Modify the deployment.yml file

Use initContainers to copy the Agent files into the main container

{{- $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:
Initialize the container and copy the probe file to the shared directory
{{- 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
# Mount volume, import probe file
{{- if .Values.skywalking.enabled }}
        - name: agent-dir
          mountPath: {{ printf "%s/%s" .Values.appHome "agent" }}
{{- end }}
Environment variables, used to set the parameters required by the probe
{{- 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 }}
Volume # statement
{{- if .Values.skywalking.enabled }}
      - name: agent-dir
        emptyDir: {}
{{- end }}
      securityContext:
        runAsUser: {{ .Values.storage.securityContext.runAsUser }}
        fsGroup: {{ .Values.storage.securityContext.fsGroup }}
Copy the code