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.浏览器访问验证
访问 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 浏览器访问验证
现在由于没有数据说一在 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.浏览器访问
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 获取数据