SkyWalking 链路追踪如何实现外部 SkyWalking-Server 监听 K8S 内部业务

1 SkyWalking 介绍

1.1 SkyWalking 简介-特点

SkyWalking 实现从请求开始和结束整个链路的跟踪、指标收集和日志记录的完整信息记录。多语言自动探针,支持 Java、GO、Python、PHP、NodeJS、LUA、Rust 等客户端。内置服务网格可观察性,支持从 Istio+Envoy Service Mesh 收集和分析数据。模块化架构,存储、集群管理、使用插件集合都可以进行自由选择。支持告警。优秀的可视化效果。

sky walking 中的 agent 也就是多语言自动探针必须和应用程序部署在一起,其实就等同于应用程序的 sidecar,如果是通过容器启动的话就需要将 sky walking 的 agent 写到 DockerFile 中

1.2 SkyWalking 简介-组件

SkyWalking 结构介绍


如上图:

SkyWalking UI 通过浏览器观察链路追踪的效果,比如说要查询某个服务的状态那就需要通过这个 UI 来观察;这个 UI 的数据来自于后端存储里面,这个后端存储的话支持 MySQL、TIDB、ES 等等

Tracing 部分就可以理解为我们的 agent

Metric 部分就是我们收集指标数据的

然后将指标收集起来通过 RPC、gRPC、HTTP 等协议将指标数据发送至 SkyWalking 服务器里面

然后在 SkyWalking-Server 里面 Tracing 是用来接收跟踪数据的、而 Metric 是用来接收指标数据,并且还能实现对数据的分析和数据的查询。不过这些数据都存储到了数据里面。也就是用户在 UI 对数据的查看都需要 SkyWalking-Server 在数据存储服务器实时对数据进行查询,所以我们的 ES 需要做成集群以避免 ES 单点失败

OAP 平台 (Observability Analysis Platform,可观测性分析平台)或 OAP Server 也就是 SkyWalking Server ,它是一个高度件化的轻量级分析程序,由兼容各种探针 Receiver(接收器) 兼容各个语言的 agent ,这个 agent 可以源源不断地通过 Receiver(接收器) 发送给 SkyWalking Server 、流式分析内核和查询内核三部分构成。

  • Receiver(接收器) :用于接收跟踪数据、接收指标数据
  • 流式分析内核:用于分析数据
  • 查询内核:用于查询数据

探针就是 agent:基于无侵入式的收集,并通过 HTTP 或者 gRPC 方式发送数据到 OAP Server,agent 将数据收集起来所以需要和应用 APP 一块启动。

存储实现 (Storage Implementors),SkyWalking OAP Server 支持多种存储实现并且提供了标准接口,可支持不同的存储后端。 这里主要使用 ES

UI 模块 (SkyWalking),通过标准的 GraphQL(Facebook在2012年开源) 协议进行统计数据查询和展示 ,其实就是从后端存储服务查询这些数据并在前端进行展示

1.3 设计模式

面向协议设计:面向协议设计是 SkyWalking 从 5.x 开始严格遵守的首要设计原则,组件之间使用标准的协议进行数据交互。

协议有探针协议和查询协议

1.3.1 探针(agent)协议

这里的探针就是对应在应用程序 APP 中的 sidecar-agent

探针上报协议:协议包括语言探针的注册、Metrics 数据上报、Tracing 数据据上报等标准,Java、Go 等探针都需要严格遵守此协议的标准。

探针交互协议:因为分布式追踪环境,探针间需要借助 HTTP Header、MQ Header 在应用之间进行通信和交互,探针交互协议就定义了交互的数据格式。

Service Mesh 协议:是 SkyWalking 对 Service Mesh 抽象的专有协议,任何 Mesh 类的服务都可以通过此协议直接上传指标数据,用于计算服务的指标数据和绘制拓扑图。

第三方协议: 对大型的第三方开源项目尤其是 Service Mesh 核心平台 Istio 和 Envoy ,提供核心协议适配,支持针对 Istio+Envoy Service Mesh 进行无缝对接。

1.3.2 数据查询协议

  • 元数据查询:查询在 SkyWalking 注册的服务、服务实例、Endpoint 等元数据信息。
  • 服务调用关系查询:查询全局、者单个服务、Endpoint 的拓扑图及依赖关系。
  • Metrics 指标查询: 查询指标数据。
  • 聚合指标查询:区间范围均值查询及 Top N 排名数据查询等。
  • Trace 查询:追踪数据的明细查询。
  • 告警查询:基于表达式,判断指标数据是否超出阈值。

1.4 skywalking 设计

模块化设计:

  • 探针收负责集数据
  • 前端负责展示数据
  • 后端负责从后端存储读写数据
  • 后端存储负责持久化数据

轻量化设计:

SkyWalking 在设计之初就提出了轻量化的设计理念,SkyWalking 使用最轻量级的 jar 包模式,基于 jar 包实现强大的数据处理和分析能力、可扩展能力和模块化能力。

1.5 skywalking 优势

兼容性好:

支持传统的分部署架构 dubbo 和 spring cloud,也支持云原生中的 Istio 和 envoy。

易于部署和后期维护:

组件化,可以自定义部署,后期横向扩容简单

高性能 :

每天数T的数据无压力

易于二次开发 :

标准的 http 和 grpc 协议,开源的项目,企业可以自主二次开发

2 部署 skywalking

部署方式:

  • 单机部署
  • docker-compose 部署
  • K8S 部署

二进制部署-架构规划:


如上图:

浏览器访问 SkyWalking-UI 的 8080 端口;然后需要在 SkyWalking-OAP:12800 中查询数据;并且这些数据都来自于 Agent ,当 agent 收集到数据之后通过 SkyWalking-OAP:11800 上传写入数据,最后 SkyWalking-OAP 再将数据存储至 ElasticSearch

这里我演示二进制部署,因为在公司中也是通过这种方式部署

2.1 二进制部署

为了还原生成环境这里我采用分开部署:注意在生产环境中需要将 ES 部署为集群

环境准备:

服务器名称 IP 资源 C/M
SkyWalking 10.0.0.139 2C/4G
ES-1 10.0.0.136 2C/2G
ES-2 10.0.0.137 2C/2G
ES-3 10.0.0.138 2C/2G

2.1.1 二进制部署 ES

1.下载 ES

root@es1:~# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-amd64.deb

# scp 到其他两台 es 服务器
root@es1:~# scp elasticsearch-7.6.2-amd64.deb 10.0.0.137:/root
root@es1:~# scp elasticsearch-7.6.2-amd64.deb 10.0.0.138:/root

2.安装

root@es1:~# dpkg -i elasticsearch-7.6.2-amd64.deb 
root@es2:~# dpkg -i elasticsearch-7.6.2-amd64.deb 
root@es3:~# dpkg -i elasticsearch-7.6.2-amd64.deb 

3.配置集群名称和 node 名称

每个 ES 节点的集群名称必须配置一样,才能创建到同一个 ES 集群中,在集群里面每个节点名称不能一样

# 修改 es1 节点
root@es1:~# vim /etc/elasticsearch/elasticsearch.yml 
cluster.name: zgy-elk-cluster1  # 集群名称必须相同
node.name: node-1               # 区分每个 node 在集群中的名称 node 名称不能一样

# 数据一般我们会放到单独的固态盘,由于这使用的是虚拟机所以我就不做修改
path.data: /var/lib/elasticsearch   

path.logs: /var/log/elasticsearch

# 监听网络,改为 0.0.0.0,写 127.0.0.1 也行
network.host: 0.0.0.0           

# 客户端监听端口
http.port: 9200                 

# 一个子网中发现主机集群 ip 地址
discovery.seed_hosts: ["10.0.0.136", "10.0.0.138","10.0.0.137"] 

# 集群主节点选举主机IP
cluster.initial_master_nodes: ["10.0.0.136", "10.0.0.138","10.0.0.137"]

# 执行数据同步的节点数,也就是说我们这个 es 集群宕了有多少个节点在才进行数据同步这里是 2
# 一般是写集群一半以上的节点
gateway.recover_after_nodes: 2

# 必须指定要删除的名称,不能通过正则模糊匹配
action.destructive_requires_name: true
root@es1:~# systemctl restart elasticsearch.service 
root@es1:~# systemctl enable --now elasticsearch.service 

4.es2 节点修改配置

# 修改 es2 节点
root@es2:~# vim /etc/elasticsearch/elasticsearch.yml 
cluster.name: zgy-elk-cluster1  # 集群名称必须相同
node.name: node-2               # 区分每个 node 在集群中的名称 node 名称不能一样
# 数据一般我们会放到单独的固态盘,由于这使用的是虚拟机所以我就不做修改
path.data: /var/lib/elasticsearch   
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.136", "10.0.0.138","10.0.0.137"] 
cluster.initial_master_nodes: ["10.0.0.136", "10.0.0.138","10.0.0.137"]
gateway.recover_after_nodes: 2
action.destructive_requires_name: true
root@es2:~# systemctl restart elasticsearch.service 
root@es2:~# systemctl enable --now elasticsearch.service 

5.es3 节点修改配置

root@es3:~# vim /etc/elasticsearch/elasticsearch.yml 
cluster.name: zgy-elk-cluster1  # 集群名称必须相同
node.name: node-3               # 区分每个 node 在集群中的名称 node 名称不能一样
path.data: /var/lib/elasticsearch   
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["10.0.0.136", "10.0.0.138","10.0.0.137"] 
cluster.initial_master_nodes: ["10.0.0.136", "10.0.0.138","10.0.0.137"]
gateway.recover_after_nodes: 2
action.destructive_requires_name: true
root@es3:~# systemctl restart elasticsearch.service 
root@es3:~# systemctl enable --now elasticsearch.service 

6.可以看到 9200 和 9300 端口已经启动

9200 是客户端端口 9300 是集群端口用来做集群通告和数据同步

root@es1:~# ss -ntl
State       Recv-Q       Send-Q               Local Address:Port               Peer Address:Port       
LISTEN      0            128                              *:9200                          *:*          
LISTEN      0            128                              *:9300   

7.浏览器访问验证

http://10.0.0.136:9200/

访问 ES 的客户端端口,可以看到集群详细信息的 json 格式

8.安装 elasticsearch可视化插件之head

在谷歌商城搜索

ElasticSearch Head

输入 ES 集群地址

到此 Elasticsearch 集群就搭建完毕了

2.1.2 二进制部署-部署skywalking server

sky walking 官网:https://skywalking.apache.org/zh/

sky walking apache 下载地址:http://archive.apache.org/dist/skywalking/

1.在 skywalking 节点上安装 jdk

root@SkyWalking:~# apt update
root@SkyWalking:~# apt install openjdk-11-jdk -y

# 安装完成
root@SkyWalking:~# java --version
openjdk 11.0.14 2022-01-18
OpenJDK Runtime Environment (build 11.0.14+9-Ubuntu-0ubuntu2.18.04)
OpenJDK 64-Bit Server VM (build 11.0.14+9-Ubuntu-0ubuntu2.18.04, mixed mode, sharing)

2.下载 skywalking-apm-es 版本

# 下载
root@SkyWalking:~# wget http://archive.apache.org/dist/skywalking/8.6.0/apache-skywalking-apm-es7-8.6.0.tar.gz

2.解压

root@SkyWalking:~# tar xf apache-skywalking-apm-es7-8.6.0.tar.gz 

3.修改存储

​ 112 行修改存储配置为 es

​ 141 行修改 ES 集群配置,多个 es 地址以 , 分割

root@SkyWalking:~# cd apache-skywalking-apm-bin-es7/

# 在主配置文件中修改存储
root@SkyWalking:~/apache-skywalking-apm-bin-es7# vim config/application.yml
# 修改下面两处配置
selector: ${SW_STORAGE:elasticsearch7}  # 修改存储为 es7 版本,这里是通过变量来引用的 elasticsearch7 配置

clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:10.0.0.136:9200,10.0.0.137:9200,10.0.0.138:9200} # SW_STORAGE_ES_CLUSTER_NODES  多个 es 地址以 ,  分割

4.监听日志

root@SkyWalking:~/apache-skywalking-apm-bin-es7# tail -f logs/*.log
# 直到日志报错或者是启动成功
# 下面就是日志提示启动成功
2022-03-17 00:32:08,492 - org.apache.skywalking.oap.server.core.cache.CacheUpdateTimer - 71 [main] INFO  [] - Cache updateServiceInventory timer start

4.启动

root@SkyWalking:~/apache-skywalking-apm-bin-es7# ./bin/startup.sh
# 提示启动成功
SkyWalking OAP started successfully!
SkyWalking Web Application started successfully!

6.端口启动默认开启 12800 、11800、8080

root@SkyWalking:~/apache-skywalking-apm-bin-es7# ss -ntl
State            Recv-Q            Send-Q                         Local Address:Port                          Peer Address:Port            
LISTEN           0                 50                                         *:12800                                    *:*               
LISTEN           0                 100                                        *:8080                                     *:*               
LISTEN           0                 128                                        *:11800                                    *:*

2.1.2.1 配置文件讲解

cluster:
   selector: ${SW_CLUSTER:zookeeper}
   # 单节点模式
   standalone:
   # zk用于管理collector集群协作.
   zookeeper:
     nameSpace: ${SW_NAMESPACE:""}
     # 多个用,分割
     hostPort: ${SW_CLUSTER_ZK_HOST_PORT:localhost:2181}
     # Retry Policy
     baseSleepTimeMs: ${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries
    maxRetries: ${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry
    # Enable ACL
    enableACL: ${SW_ZK_ENABLE_ACL:false} # disable ACL in default
    schema: ${SW_ZK_SCHEMA:digest} # only support digest schema
    expression: ${SW_ZK_EXPRESSION:skywalking:skywalking}
   # 分布式 kv 存储设施,类似于zk,但没有zk重型(除了etcd,consul、Nacos等都是类似功能)
   # etcd:
      # serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
      # 多个节点用逗号分隔, 如: 10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379
      # hostPort: ${SW_CLUSTER_ETCD_HOST_PORT:localhost:2379}
core:
   selector: ${SW_CORE:default}
   default:
      # 混合角色:接收代理数据,1级聚合、2级聚合
      # 接收者:接收代理数据,1级聚合点
      # 聚合器:2级聚合点
      role: ${SW_CORE_ROLE:Mixed} # Mixed/Receiver/Aggregator

       # rest 服务地址和端口
      restHost: ${SW_CORE_REST_HOST:localhost}
      restPort: ${SW_CORE_REST_PORT:12800}
      restContextPath: ${SW_CORE_REST_CONTEXT_PATH:/}

      # gRPC 服务地址和端口
      gRPCHost: ${SW_CORE_GRPC_HOST:localhost}
      gRPCPort: ${SW_CORE_GRPC_PORT:11800}

      downsampling:
      - Hour
      - Day
      - Month

      # 设置度量数据的超时。超时过期后,度量数据将自动删除.
      # 单位分钟
      recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:90}

      # 单位分钟
      minuteMetricsDataTTL: ${SW_CORE_MINUTE_METRIC_DATA_TTL:90}

      # 单位小时
      hourMetricsDataTTL: ${SW_CORE_HOUR_METRIC_DATA_TTL:36}

      # 单位天
      dayMetricsDataTTL: ${SW_CORE_DAY_METRIC_DATA_TTL:45}

      # 单位月
      monthMetricsDataTTL: ${SW_CORE_MONTH_METRIC_DATA_TTL:18}

storage:
   selector: ${SW_STORAGE:elasticsearch7}
   elasticsearch7:
      # elasticsearch 的集群名称
      nameSpace: ${SW_NAMESPACE:"TEST-ES"}

      # elasticsearch 集群节点的地址及端口
      clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:192.168.1.1:9200}

      # elasticsearch 的用户名和密码
      user: ${SW_ES_USER:""}
      password: ${SW_ES_PASSWORD:""}

      # 设置 elasticsearch 索引分片数量
      indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}

      # 设置 elasticsearch 索引副本数
      indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}

      # 批量处理配置
      # 每2000个请求执行一次批量
      bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:2000}

      # 每 20mb 刷新一次内存块
      bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20}

      # 无论请求的数量如何,每10秒刷新一次堆
      flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10}

      # 并发请求的数量
      concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2}

      # elasticsearch 查询的最大数量
      metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}

      # elasticsearch 查询段最大数量
      segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}

      profileTaskQueryMaxSize: ${SW_STORAGE_ES_QUERY_PROFILE_TASK_SIZE:200}
      advanced: ${SW_STORAGE_ES_ADVANCED:""}

2.1.2.1 浏览器访问验证

http://10.0.0.139:8080/

现在由于没有数据说一在 UI 中看不到任何东西

2.1.2.2 验证 elasticsearch 数据

SW 就为 sky Walking 写入的数据

3 复杂案例:K8S 运行 tomcat 服务实现链路追踪

3.1 构建基础系统镜像

1 创建 centos 目录

root@node:~# mkdir centos
root@node:~# cd centos

2.编写 dockerfile 文件

root@node:~/centos# vim Dockerfile 
#自定义Centos 基础镜像
FROM centos:7.8.2003 
MAINTAINER zhang.g.y

# 安装依赖
RUN yum install -y vim wget tree  lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop

3.构建镜像

root@node:~/centos# docker build -t centos-base:7.8.2003 .

3.2 tomcat 步骤

3.2.1 构建 JDK 镜像

在构建 tomcat 之前需要构建 JDK 镜像

1.编写 dockerfile

root@master:~# mkdir jdk-1.8.212
root@master:~# cd jdk-1.8.212/

root@master:~/jdk-1.8.212# vim Dockerfile 

#JDK Base Image 还是基于gangcaide base 镜像
FROM centos-base:7.8.2003

MAINTAINER zhangguiyuan

ADD jdk-8u212-linux-x64.tar.gz /usr/local/src/
RUN ln -sv /usr/local/src/jdk1.8.0_212 /usr/local/jdk 
ADD profile /etc/profile

# 配置环境变量
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin

3.配置文件

root@master:~# vim profile 
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}

if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then 
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge
export LANG=en_US.UTF-8
export HISTTIMEFORMAT="%F %T `whoami` "

export JAVA_HOME=/usr/local/jdk
export TOMCAT_HOME=/apps/tomcat
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar

4.下载 jdk,(jdk 需要自行登录至甲骨文网站下载)

root@master:~/jdk-1.8.212# ls
Dockerfile  jdk-8u212-linux-x64.tar.gz  profile

5.构建镜像

root@master:~/jdk-1.8.212# docker build -t jdk-base:v8.212 .

6.验证镜像

root@master:~/jdk-1.8.212# docker run -it --rm jdk-base:v8.212 /bin/bash

[root@64eb96e4bd7c /]# java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)

3.1.2 构建 tomcat 基础镜像

1.下载tomcat 安装包

root@master:~# mkdir tomcat-base
root@master:~# cd tomcat-base/

root@master:~/tomcat-base# wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.43/bin/apache-tomcat-8.5.43.tar.gz

2.编写 dockerfile

root@master:~/tomcat-base# vim Dockerfile 

#Tomcat 8.5.43基础镜像
FROM jdk-base:v8.212

MAINTAINER zhangguiyaun

# apps 用来存放 tomcat 运行程序 
# /data/tomcat/webapps 用来存储业务代码
RUN mkdir /apps /data/tomcat/webapps /data/tomcat/logs -pv

# tomcat 安装包
ADD apache-tomcat-8.5.43.tar.gz  /apps              

# 创建 tomcat 用户,后期需要使用 nginx 用户来启动
# 不然后期可能会报权限拒绝 403 的状态码
# 前端 nginx 是通过什么用户启动后端 tomcat 就需要使用该用户启动
RUN useradd tomcat -u 2022 && ln -sv /apps/apache-tomcat-8.5.43 /apps/tomcat && chown -R tomcat.tomcat /apps /data -R

3.构建

root@master:~/tomcat-base# docker build -t tomcat-base:v8.5.43  .

3.1.3 构建业务镜像

1.创建目录

root@master:~# mkdir tomcat-app1
root@master:~# cd tomcat-app1/

2.编写启动 tomcat 脚本

root@master:~/tomcat-app1# vim run_tomcat.sh 
#!/bin/bash
# 通过 tomcat 用户启动 tomcat
su - tomcat -c "/apps/tomcat/bin/catalina.sh start"

# 挂后台运行容器
tail -f /etc/hosts

3.编辑 dockerfile

[17:21:07 root@master tomcat-app1]#vim Dockerfile 
FROM tomcat-base:v8.5.43

# catalina.sh 文件中有启动 skywalking 的环境变量
# CATALINA_OPTS="$CATALINA_OPTS -javaagent:/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS :指定 sky walking agent 的 jar 包路径 /skywalking-agent/skywalking-agent.jar
# 把这一行插入到 catalina.sh 文件第二行
RUN sed -i '2i CATALINA_OPTS="$CATALINA_OPTS -javaagent:/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS' /apps/tomcat/bin/catalina.sh

# 导入 tomcat
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh

RUN chown  -R tomcat.tomcat /apps/

EXPOSE 8080 8443

# 启动 tomcat
CMD ["/apps/tomcat/bin/run_tomcat.sh"]

4.给当前的所有 sh 脚本添加执行权限

root@master:~/tomcat-app1# chmod  +x *.sh

5.构建

root@master:~/tomcat-app1# docker build -t tomcat-app1:v1 .

6.验证 tomcat 镜像是否能够正常使用

root@master:~/tomcat-app1# docker run -it --rm -p 7070:8080 tomcat-app1:v1

7.浏览器访问

Apache Tomcat/8.5.43

3.3 构建 sidecar 镜像

1 构建 skywalking-agent sidecar 镜像

root@master:~# mkdir skywalking/
root@master:~# cd skywalking/

# 下载
root@master:~/skywalking# wget https://archive.apache.org/dist/skywalking/java-agent/8.8.0/apache-skywalking-java-agent-8.8.0.tgz
FROM alpine:3.8

ADD apache-skywalking-java-agent-8.8.0.tgz /apps

# 定义当前服务为 tomcat,10.0.0.139 为链接 server 端地址
RUN sed -i 's#agent.namespace=${SW_AGENT_NAMESPACE:}#agent.namespace=${SW_AGENT_NAMESPACE:tomcat1}#g' /apps/skywalking-agent/config/agent.config && \
    sed -i 's#Your_ApplicationName#tomcat1#g' /apps/skywalking-agent/config/agent.config && \
    sed -i 's#127.0.0.1#10.0.0.139#g' /apps/skywalking-agent/config/agent.config 

2 完成 Docker 文件编写后,执行镜像构建命令

root@master:~/skywalking# docker build .  -t skywalking-agent-sidecar:v1.8.8.0

3.4 编写 yaml

上面我们通过手工构建的方式构建了 SkyWalking Java Agent 的公共 Docker 镜像,接下来我们将演示如何通过编写 Kubernetes 服务发布文件,来将 Java 服务发布到 K8s 集群的过程中自动以 SideCar 的形式集成 Agent、并接入 SkyWalking 服务。

2.编写yaml 文件

root@master:~/skywalking# cat sky-dmeo.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: sky
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-skywalking
  namespace: sky
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-skywalking
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: demo-skywalking
    spec:
      nodeName: master
      initContainers:
        - name: init-skywalking-agent
          image: skywalking-agent-sidecar:v1.8.8.0
          imagePullPolicy: IfNotPresent
          command:
            - 'sh'
            - '-c'
            - 'set -ex;mkdir -p /vmskywalking/agent;cp -r /apps/skywalking-agent/* /vmskywalking/agent;'
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
        - image: tomcat-app1:v1
          imagePullPolicy: IfNotPresent
          name: tomcat
          ports:
            - containerPort: 8080
              protocol: TCP
          volumeMounts:
            - mountPath: /skywalking-agent/
              name: skywalking-agent
      volumes:
        - name: skywalking-agent
          emptyDir: {}
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: web-tomcat-app1-service-label
  name: sky-tomcat
  namespace: sky
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 30080 # tomcat 本身是不用对外暴露端口该端口只用于 pod 起来之后测试
  selector:
    app: demo-skywalking

3.5 验证

访问 tomcat Apache Tomcat/8.5.43

http://10.0.0.139:8080/ skywalking 获取数据

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇