写在最前
在前面,我们成功使用 KubeSphere 部署了若依管理系统。接下来我们可以对其进行小幅改造,以实现与 SkyWalking 的接入,从而实现可视化链路的监控与分析。
1. 前置条件
2. 官方例子
https://hub.docker.com/r/apache/skywalking-java-agent
使用此镜像作为 Kubernetes 服务的 sidecar
apiVersion: v1
kind: Pod
metadata:
name: agent-as-sidecar
spec:
restartPolicy: Never
volumes:
- name: skywalking-agent
emptyDir: { }
containers:
- name: agent-container
image: apache/skywalking-java-agent:8.4.0-alpine
volumeMounts:
- name: skywalking-agent
mountPath: /agent
command: [ "/bin/sh" ]
args: [ "-c", "cp -R /skywalking/agent /agent/" ]
- name: app-container
image: springio/gs-spring-boot-docker
volumeMounts:
- name: skywalking-agent
mountPath: /skywalking
env:
- name: JAVA_TOOL_OPTIONS
value: "-javaagent:/skywalking/agent/skywalking-agent.jar"
3. 配置变更
3.1 configmap
我在代码中的Dockerfile中已经预先配置好了一个叫JAVA_OPS的环境变量了,configmap配置到这个变量就能动态变更jvm参数。
kind: ConfigMap
apiVersion: v1
metadata:
name: java-ops
namespace: ruoyi
annotations:
kubesphere.io/creator: admin
data:
JAVA_OPS: >
-server
-Dskywalking.collector.backend_service=skywalking-oap.basic.svc.cluster.local:11800
-javaagent:/skywalking/agent/skywalking-agent.jar
3.2 Jenkinsfile
使用 initContainers
运行 skywalking-java-agent
,并将其复制到一个 skywalking-agent的emptyDir
中,在运行业务容器时挂载该卷目录以获取 skywalking-agent.jar
,通过读取 java-ops
的configmap并将配置放到JAVA_OPS环境变量以动态生成jvm连接参数,并利用 SW_AGENT_NAME
变量设置skywalking模块名称。
pipeline {
agent {
node {
label 'maven'
}
}
stages {
stage('拉取项目') {
agent none
when {
environment name: 'BUILD_ENV', value: 'UAT_CICD'
}
steps {
container('maven') {
git(credentialsId: 'gitee-secret', branch: 'tanqidi_v3.6.4', url: 'https://gitee.com/tanqidi/RuoYi-Cloud_1.git', changelog: true, poll: false)
}
}
}
stage('项目编译') {
agent none
when {
environment name: 'BUILD_ENV', value: 'UAT_CICD'
}
steps {
container('maven') {
sh 'mvn -Dmaven.test.skip=true clean package'
}
}
}
stage('镜像构建') {
agent none
when {
environment name: 'BUILD_ENV', value: 'UAT_CICD'
}
steps {
container('maven') {
script {
def environment = params.MODULE_NAME
if (environment == "ruoyi-auth" || environment == "ruoyi-gateway") {
sh 'cd $MODULE_NAME && sed -i \'s/dev/uat/g\' ./Dockerfile && docker build -t $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION .'
} else if (environment == "ruoyi-monitor") {
sh 'cd ruoyi-visual/$MODULE_NAME && sed -i \'s/dev/uat/g\' ./Dockerfile && docker build -t $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION .'
} else {
sh 'cd ruoyi-modules/$MODULE_NAME && sed -i \'s/dev/uat/g\' ./Dockerfile && docker build -t $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION .'
}
}
}
}
}
stage('镜像推送') {
agent none
when {
environment value: 'UAT_CICD', name: 'BUILD_ENV'
}
steps {
container('maven') {
withCredentials([usernamePassword(credentialsId : 'aliyun-harbor-secret' ,passwordVariable : 'name' ,usernameVariable : 'passwd' ,)]) {
sh 'echo "$name" | docker login $REGISTRY -u "$passwd" --password-stdin'
sh 'docker push $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION'
}
}
}
}
stage('部署到UAT环境') {
agent none
steps {
container('maven') {
withCredentials([kubeconfigFile(credentialsId: "$KUBECONFIG_CREDENTIAL_ID", variable: 'KUBECONFIG')]) {
script {
sh "echo \'${DEPLOY_YAML}\' > deploy.yaml"
sh "cat deploy.yaml"
sh "envsubst < deploy.yaml | kubectl apply -f -"
}
}
}
}
}
}
environment {
KUBECONFIG_CREDENTIAL_ID = 'k8s-kubeconfig'
REGISTRY = 'registry.cn-hangzhou.aliyuncs.com'
HARBOR_NAMESPACE = 'tanqidi-temp'
PROJECT_NAMESPACE = 'ruoyi'
DEPLOY_YAML = '''
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ${MODULE_NAME}
name: ${MODULE_NAME}
namespace: ${PROJECT_NAMESPACE}
spec:
replicas: 1
selector:
matchLabels:
app: ${MODULE_NAME}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
template:
metadata:
labels:
app: ${MODULE_NAME}
appType: ruoyi-service
spec:
volumes:
- name: skywalking-agent
emptyDir: { }
imagePullSecrets:
- name: harbor
initContainers:
- name: skywalking-java-agent
image: 'apache/skywalking-java-agent:9.3.0-java21'
command:
- /bin/sh
args:
- '-c'
- cp -R /skywalking/agent /agent/
volumeMounts:
- name: skywalking-agent
mountPath: /agent
containers:
- name: ${MODULE_NAME}
imagePullPolicy: Always
image: $REGISTRY/$HARBOR_NAMESPACE/$MODULE_NAME:$MODULE_VERSION
volumeMounts:
- name: skywalking-agent
mountPath: /skywalking
ports:
- containerPort: 8080
protocol: TCP
env:
- name: JAVA_OPS
valueFrom:
configMapKeyRef:
name: java-ops
key: JAVA_OPS
- name: SW_AGENT_NAME
value: ${MODULE_NAME}
resources:
limits:
cpu: \'1\'
memory: 2Gi
requests:
cpu: 25m
memory: 850Mi
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: ${MODULE_NAME}
namespace: ${PROJECT_NAMESPACE}
labels:
app: ${MODULE_NAME}
spec:
ports:
- port: 8080
targetPort: 8080
selector:
app: ${MODULE_NAME}
type: ClusterIP
sessionAffinity: None
'''
}
parameters {
choice(name: 'MODULE_NAME', choices: '''ruoyi-auth
ruoyi-gateway
ruoyi-system
ruoyi-job
ruoyi-monitor
ruoyi-file''', description: '模块构建')
choice(name: 'BUILD_ENV', choices: '''UAT_CICD
UAT_CD''', description: '构建环境')
string(name: 'MODULE_VERSION', defaultValue: 'v0.0Beta', description: '模块版本')
}
}