k8s-apm
apm全链路追踪
产品对比
pinpoint
Pinpoint是用 Java / PHP编写的用于大型分布式系统的 APM(应用程序性能管理)工具。受Dapper的启发,Pinpoint 提供了一种解决方案,通过跟踪分布式应用程序中的事务来帮助分析系统的整体结构以及其中的组件如何互连。
Skywalking
分布式系统的应用程序性能监控工具,专为微服务、云原生和基于容器的 (Kubernetes) 架构而设计。
CAT
- CAT 是基于 Java 开发的实时应用监控平台,为美团点评提供了全面的实时监控告警服务。
- CAT 作为服务端项目基础组件,提供了 Java, C/C++, Node.js, Python, Go 等多语言客户端,已经在美团点评的基础架构中间件框架(MVC框架,RPC框架,数据库框架,缓存框架等,消息队列,配置系统等)深度集成,为美团点评各业务线提供系统丰富的性能指标、健康状况、实时告警等。
- CAT 很大的优势是它是一个实时系统,CAT 大部分系统是分钟级统计,但是从数据生成到服务端处理结束是秒级别,秒级定义是48分钟40秒,基本上看到48分钟38秒数据,整体报表的统计粒度是分钟级;第二个优势,监控数据是全量统计,客户端预计算;链路数据是采样计算。
Zipkin
bonree(收费)
基调听云
Skywalking
helm-k8s安装
1 | #添加仓库 |
springboot接入Skywalking
查看Skywalking oap服务地址
集群管理
->应用负载
->服务
->skywalking-oap
->dns+服务端口=skywalk oap 后端服务地址
idea agent接入
编辑vm参数,添加如下参数:
java -javaagent:~/skywalking/agent/skywalking-agent.jar -Dskywalking.agent.service_name=your-service-name -Dskywalking.collector.backend_service=127.0.0.1:11800
通过k8s sidecar无侵入接入
在kind: Deployment
配置文件添加如下配置:
1 | initContainers: #新添加初始化容器,主要用于拷贝skywalking-agent.jar包,也可以在dockerfile里面的基础镜像直接加,就不用初始化容器 |
常见问题
使用hutool工具的
HttpUtil.get
方法发现不能追踪链路?原理:skywalking版本9.2.0,升级agent镜像,升级之后能追踪。
解决:将
apache/skywalking-base:8.1.0-es7
替换成 apache/skywalking-java-agent:8.13.0-java8
参考
k8s 灰度发布
概念
KubeSphere 服务网格基于开源项目 Istio 构建,可以控制应用程序不同部分之间的通信方式。其中,灰度发布策略为用户在不影响微服务之间通信的情况下测试和发布新的应用版本发挥了重要作用。
服务网格
服务网格基于 Istio,将微服务治理和流量管理可视化。它拥有强大的工具包,包括熔断机制、蓝绿部署、金丝雀发布、流量镜像、链路追踪、可观测性和流量控制等。
istio
架构
Istio 服务网格从逻辑上分为数据平面和控制平面。
数据平面 由一组智能代理(Envoy)组成,被部署为 Sidecar。这些代理负责协调和控制微服务之间的所有网络通信。它们还收集和报告所有网格流量的遥测数据。
组件一: Envoy 特性动态服务发现、负载均衡、TLS 终端、HTTP/2 与 gRPC 代理、熔断器、健康检查、基于百分比流量分割的分阶段发布、故障注入、丰富的指标。
控制平面 管理并配置代理来进行流量路由。
组件二:Istiod 提供服务发现、配置和证书管理。
部署模型
- 集群模型:单一/多集群
- 网络模型:单一/多网络
- 控制平面模型
- 身份和信任模型:网格内/网格之间信任
- 网格模型:单一/多网格
- 租户模型:命名空间租赁/集群租户模型
Ingress
控制 Istio 服务网格的入口流量。
Egress
控制 Istio 服务网格的出口流量。
灰度发布策略
当您在 KubeSphere 中升级应用至新版本时,灰度发布可以确保平稳过渡。采用的具体策略可能不同,但最终目标相同,即提前识别潜在问题,避免影响在生产环境中运行的应用。这样不仅可以将版本升级的风险降到最低,还能测试应用新构建版本的性能。
蓝绿部署
蓝绿发布提供零宕机部署,即在保留旧版本的同时部署新版本。在任何时候,只有其中一个版本处于活跃状态,接收所有流量,另一个版本保持空闲状态。如果运行出现问题,您可以快速回滚到旧版本。
- 特点:任何时刻只有一个环境接收流量。
金丝雀发布
控制一部分流量到新的环境,待确认没问题,便可把所有流量转移到新环境。
- 特点:流量逐步转移,风险降到最低。
流量镜像
复制实时产生的流量推送至新部署的镜像环境。
- 特点:可以对比新旧环境流量处理的效率,测试集群,测试数据库。
实战
部署Bookinfo示例应用
启用服务组件Istio
创建一个项目
为新建的项目设置网关:
项目设置-->高级设置-->设置网关-->NodePort/LoadBalancer
在
应用负载-->应用模版-->如何使用应用治理--部署示例应用
然后一路下一步即可在
应用负载-->自制应用-->bookinfo-->点击访问
进行访问应用访问地址
http://productpage.exxk-lab.10.25.24.12.nip.io:31612/
分析:productpage.exxk-lab.10.25.24.12.nip.io:31612
是dns泛域名,nip.io是一个免费域名解析服务,会自动指向10.25.24.12
不需要配置hosts映射文件。
给部署的服务添加网关,并设置统一的前缀
为新建的项目设置网关:
项目设置-->高级设置-->设置网关-->NodePort
添加路由:
应用负载-->应用路由-->创建
指定域名:
server-name.10.255.242.18.nip.io
指定路径(统一前缀):
/前缀(/|$)(.*)
指定路径(不加前缀):
/
添加注解(统一前缀):
nginx.ingress.kubernetes.io/app-root=/前缀
和nginx.ingress.kubernetes.io/rewrite-target=/$2
对应的配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: transport-server
namespace: transport-server
annotations:
kubesphere.io/creator: '81003863'
nginx.ingress.kubernetes.io/app-root: /transport
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: transport-server.10.255.242.18.nip.io
http:
paths:
- path: /transport(/|$)(.*)
pathType: ImplementationSpecific
backend:
serviceName: transport-manage
servicePort: 8088
参考
helm上传私有chart仓库
helm chart语法
github helm仓库
在githuab创建helm-charts仓库
克隆代码到本地
git clone git@github.com:iexxk/helm-charts.git
进入
cd helm-charts
目录,创建目录执行mkdir charts
创建发布流程文件,执行
mkdir -p .github/workflows
创建github操作流文件.github/workflows/release.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25name: Release Charts
on:
push:
branches:
- main
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.1.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"进入github项目页面创建分支
gh-pages
创建chart,进入charts目录,执行
helm create nginx-file-browser
创建nginx-file-browser
项目依次执行
git add .
和git commit -m "init"
和git push
等待github编译部署成功,
gh-pages
分支内会多一个或更新yaml的文件同步到artifacthub,在控制面板点击添加,输入名字:exxk,和url:https://iexxk.github.io/helm-charts
等待2+分钟,刷新,就能搜索到自己github仓库的chart了。
测试使用
1 | helm repo add exxk https://iexxk.github.io/helm-charts #添加仓库 |
harbor helm仓库
编辑好chart模版文件
执行
helm package -d <chart所在目录> <chart名称>
,会生成一个压缩包,名字为<chart名称>-<chart文件内的version>.tgz
eg:helm package -d appchart-uat-cd appchart-uat-cd
在目录appchart-uat-cd
会生成appchart-uat-cd-1.0.0.tgz
登陆harbor在
项目-->项目名-->helm Charts-->上传
,点击上传按钮在chart一栏点击选择,然后上传打包好的chart压缩包1
2
3
4#也可以使用push命令上传
docker login harbor.xxx.com.cn
helm chart save CHART_PATH harbor.xxx.com.cn/cd-dev-1/REPOSITORY[:TAG]
helm chart push harbor.xxx.com.cn/cd-dev-1/REPOSITORY[:TAG]登陆harbor在
项目-->项目名-->配置管理-->项目仓库
勾上☑️公开,然后就可以使用了chart包使用地址为
1
2CHARTS_REPO = 'https://harbor.exxk.com.cn/chartrepo/cd-dev-1/charts'
CHARTS_NAME = 'appchart-uat-cd-1.0.0.tgz'更新使用部署命令
1
helm3 upgrade --install --history-max=$HISTORY_MAX manage-app$HELM_VER $CHARTS_REPO1/$CHARTS_NAME1 -n manage-server -f z-k8s-helm/uat/val-manage-app.yaml --set image.repository=$CICD_REGISTRY/$HARBOR_NAMESPACE/manage-app:$CICD_SEQUENCE,currentImage=$CURRENT_IMAGE
常见问题
国内拉去release压缩发布版本时,因为网络原因容易失败。
解决:
引入最新版helm/chart-releaser-action自动发布,修改helm-charts/.github/workflows/release.yml文件内容如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34name: Release Charts
on:
push:
branches:
- main
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.4.1
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- name: github fast
run: |
git status
git checkout gh-pages
git pull
ls
sed -i "s/github.com/download.fastgit.org/g" index.yaml
git add index.yaml
git commit -m "update url"
git push如果chart下载失败,检查仓库是否设置为公开。
参考
注意事项
版本号不变化,是不会覆盖发布的,注意每次修改Chart.yaml
的版本号version: 0.1.1
ubuntu-strongswan
vpn选型
- openvpn: mac需要单独安装客户端,虽然以前安装过,暂时不考虑
- strongswan:不需要客户端,但是放在容器不知道为啥通过127.0.0.1连不上
- algo:
- SoftEther:
- Streisand:
- WireGuard:
strongswan安装(mac不能连接)
1 |
|
错误:mac vpn 连接 发生意外错误 49: Can’t assign requested address
解决: 没找到解决方案,放弃
1 | docker run -d --name snx-vpn --cap-add=ALL \ |
参考
checkpoint-snx-docker-vpn
需求,电脑想连2个check point vpn,但是网上客户端支持一个
因此另一个打算用snx加容器进行部署然后在用snell来代理到surge上面进行访问,因此需要制作一个snx加上snell的镜像。
采用snell的原因,比较简单,其他的strongSwan、ss都比较复杂。
编译源码件iexxk/checkpoint-snx-snell
使用
1 | #启动容器 |
自定义修改配置
修改配置可以修改容器内这个/etc/snell/snell-server.conf
配置文件,可以修改psk密码(如果暴露在外一定要修改密码)和端口
客户端配置
配置代理
进入surge-->代理-->策略-->规则判断-->新建一个代理
配置
- 服务器地址:容器的宿主机地址(本机就127.0.0.1)
- 端口:默认500
- PSK:默认2iPRYDZyOVfjRwt9
- 混淆:TLS
然后根据那些地址自己要走代理的地方设置走该代理即可
配置路由规则
进入surge-->代理-->规则-->新建一个规则
,添加容器里面的路由到规则里面
终端使用代理
在当前终端执行export https_proxy=http://127.0.0.1:6152;export http_proxy=http://127.0.0.1:6152;export all_proxy=socks5://127.0.0.1:6153
退出终端失效,测试不能用ping,ping不是http协议和socks5协议,用curl -vv https://www.google.com
终端使用ssh代理
ssh -o "ProxyCommand=nc -X 5 -x 127.0.0.1:6153 %h %p" root@10.1.1.10
royal TSX使用代理
连接右键-->properties-->advanced-->SSH-->Additional SSH Options
添加该内容-o "ProxyCommand=nc -X 5 -x 127.0.0.1:6153 %h %p"
常见问题
SNX: Virtual Network Adapter initialization and configuration failed. Try to reconnect.
解决:
apt-get install kmod
SNX: Routing table configuration failed. Try to reconnect.
解决:
docker run --cap-add=ALL -v /lib/modules:/lib/modules -t checkpoint-snx-snell:22.9.21
添加--cap-add=ALL
SNX: Connection aborted.
解决:去vpn服务器用sifra浏览器访问,下载ssl network extender(linux)版本,然后执行
docker cp snx_install.sh snx-vpn:/
进入容器执行chmod +x snx_install.sh && ./snx_install.sh
解决2: 升级docker版本之后
You’re currently on version 4.11.1 (84025). The latest version is 4.13.1 (90346)
也提示该错误,回退版本到4.11.1(84025)解决。Another session of SNX is already running, aborting…
解决:执行
snx -d
断开连接,然后重新连接。
参考
k8s job任务
需求
因为Jenkins经常产生尸体容器,所以需要一个定时任务清理错误的容器
解决方案-采用
原生命令:kubectl get pods -n kubesphere-devops-system |grep Error |awk '{print $1}' |xargs kubectl delete pod -n kubesphere-devops-system
集群管理—>配置中心—>服务账户—>项目[kubesphere-devops-system]—>创建[test]—>选择管理员权限
单独创建的原因:defalut的账户没有删除的权限,通过创建账号可以生产token,然后修改权限即可,创建的容器会默认加载defalut的token,但是因为没权限,所以需要自己挂载。
集群管理—>应用负载—>任务—>定时任务[kubesphere-devops-system]—>创建[jenkins-agent-clean]
容器镜像配置:
1
2
3镜像:bitnami/kubectl:latest
运行命令:sh
参数:kubectl get pods -n kubesphere-devops-system |grep Error|awk '{print $1}' |xargs kubectl delete pod -n kubesphere-devops-system挂载存储配置:
1
2
3密钥:test-token-xxxx
模式:只读
挂载目录:/var/run/secrets/kubernetes.io/serviceaccount
生成的完整的配置
1 | apiVersion: batch/v1beta1 |
k8s-loki
旧版安装
loki-stack-2.1.2 会安装有状态副本集loki和守护进程集loki-promtail
1 | helm repo add loki https://grafana.github.io/loki/charts |
单独的grafana安装
1 | helm repo add grafana https://grafana.github.io/helm-charts |
新版安装
1 | helm upgrade --install loki grafana/loki-stack --set grafana.enabled=true |
配置
Loki的部署如果是emptyDir: {}
数据不会持久话,重启会丢失,因此尽量配置nfs目录挂载,重启就不会丢失了。
查看路径: 平台管理--->集群--->配置中心--->密钥--->[filter]kubesphere-loki-system--->loki--->右侧眼睛(不然是加密的)
修改:在查看路径的基础上 更多操作--->编辑密钥--->loki.yaml--->编辑
Loki.yaml配置详解
1 | auth_enabled: false |
参考
常见错误
启动过报错
1
level=error ts=2022-08-10T01:49:48.744952015Z caller=table.go:81 msg="failed to cleanup table" name=index_19214
k8s-nfs
创建nfs服务
1 | yum install rpcbind nfs-utils #所有机器都要安装,他是通过宿主机来挂载的 |
排查问题相关命令
1 | showmount -e localhost #查询本机nfs共享目录情况 |
k8s配置使用nfs存储类nfs-client-provisioner
旧版不支持kubernetes 1.20以上版本
1 | helm repo add stable http://mirror.azure.cn/kubernetes/charts |
1 | helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ |
使用
创建pvc,新建nginx-pvc-nfs.yaml
文件内容如下
1 | apiVersion: v1 |
执行kubectl apply -f nginx-pvc-nfs.yaml
,检查pvc是否创建成功
创建部署,新建nginx-deployment.yaml
文件,内容如下
1 | apiVersion: apps/v1 |
执行kubectl apply -f nginx-deployment.yaml
总结
nfs-client-provisioner容器只有在创建pvc的时候会通过该容器来连接管理nfs,pvc创建成功之后就与nfs-client-provisioner无关了,不管他是否还在运行。
nfs的挂载不是在容器内部,还是依赖于宿主机,因此宿主机需要有挂载的依赖等等
查看nfs的挂载情况
可以在pod所在机器执行df -h
可以看到类似下面的输出
1 | 10.25.207.176:/mnt/data/kubesphere-loki-system-loki-storage-pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588 9.8G 1.8G 7.5G 19% /var/lib/kubelet/pods/4d276910-7529-4355-8d92-6cfa1da68825/volumes/kubernetes.io~nfs/pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588 |
问题
nfs-client-provisioner容器报错:
unexpected error getting claim reference: selfLink was empty, can't make reference
原因:kubernetes在1.20版本移除了SelfLink,kubernetes Deprecate and remove SelfLink
解决:nfs-client-provisioner使用新版
拉去镜像报错:
Back-off pulling image "k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2"
解决:使用docker代理镜像在线生成地址
部署nginx时,使用挂载卷,多台时,其中一台报错如下
1
2
3
4异常 FailedMount 2 分钟前
(近 4 分钟发生 2 次) kubelet Unable to attach or mount volumes: unmounted volumes=[nginx-data], unattached volumes=[nginx-data kube-api-access-vq8pp]: timed out waiting for the condition
异常 FailedMount 1 秒前
(近 7 分钟发生 11 次) kubelet MountVolume.SetUp failed for volume "pvc-bb951005-5152-4ab8-ba6c-251d11af5c7a" : mount failed: exit status 32 Mounting command: mount Mounting arguments: -t nfs 192.168.4.2:/share/default-nginx-pvc-pvc-bb951005-5152-4ab8-ba6c-251d11af5c7a /var/lib/kubelet/pods/f274b225-5cec-432b-8b84-35f9355b0486/volumes/kubernetes.io~nfs/pvc-bb951005-5152-4ab8-ba6c-251d11af5c7a Output: mount.nfs: access denied by server while mounting 192.168.4.2:/share/default-nginx-pvc-pvc-bb951005-5152-4ab8-ba6c-251d11af5c7a解决:修改
/etc/exports
添加权限客户端连接测试时
1
2
3
4
5
6
7
8[root@xxx mnt]# mount -t nfs 10.255.7.6:/mnt/data /mnt/test
mount: 文件系统类型错误、选项错误、10.255.7.6:/mnt/data 上有坏超级块、
缺少代码页或助手程序,或其他错误
(对某些文件系统(如 nfs、cifs) 您可能需要
一款 /sbin/mount.<类型> 助手程序)
有些情况下在 syslog 中可以找到一些有用信息- 请尝试
dmesg | tail 这样的命令看看。解决:安装nfs客户端:
yum install -y nfs-utils
和systemctl start nfs-utils
错误日志如下:
1
MountVolume.SetUp failed for volume "pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588" : mount failed: exit status 32 Mounting command: systemd-run Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/bb3fdc10-38de-4437-b8df-81b207e57f1d/volumes/kubernetes.io~nfs/pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588 --scope -- mount -t nfs 10.255.247.176:/mnt/data/kubesphere-loki-system-loki-storage-pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588 /var/lib/kubelet/pods/bb3fdc10-38de-4437-b8df-81b207e57f1d/volumes/kubernetes.io~nfs/pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588 Output: Running scope as unit run-62186.scope. mount: wrong fs type, bad option, bad superblock on 10.255.247.176:/mnt/data/kubesphere-loki-system-loki-storage-pvc-dc2431fb-5352-4265-8a9d-0a11b69d8588, missing codepage or helper program, or other error (for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program) In some cases useful info is found in syslog - try dmesg | tail or so.
解决:简短错误信息就是mount 32错误,基本就是挂载忙,或者宿主机没有安装
nfs-utils
,因此集群所有节点最好执行安装yum install -y nfs-utils
,不然部署的时候随机换了一台机器就会提示该错误
uniapp iOS 打包
ios原生工程配置
- Hbuilder导入vue项目
- 在Hbuilder执行
npm install
- 导入资源:在Hbuilder点击
发行==>原生App-本地打包==>生产本地打包App资源
,日志会输出一个项目 'xxx-app'导出成功,路径为:/Users/xx/workspace/xxx-app/dist/resources/__UNI__xxx/www
- 下载SDK(最新iOS平台SDK下载)
- 解压SDK,然后双击
/Users/xxxx/3.4.18/SDK/HBuilder-Hello/HBuilder-Hello.xcodeproj
会通过Xcode打开 - 复制第3步生成的
__UNI__xxx
目录到xcode的HBuilder-Hello/HBuilder-Hello/Pandora/apps/
,把原来里面那个删除掉 - 修改Xcode项目的infoPlist的中英文件的
CFBundleDisplayName
的值,这个值是app显示的名字 - 修改Xcode项目里面的control的appid为打包的目录名。
- 修改Xcode项目的
general=>TARGETS=>HBuilder=>Identity
的四个信息和Hbuilder里面manifest.json里面的基础配置对应。 - 安装证书,拿到两个证书文件,双击
.p12
文件 - 修改Xcode项目的
Signing=>TARGETS=>HBuilder=>release
发布证书的信息,自动签名勾选去掉。(注意证书是发布还是开发,修改对应的) - 修改Xcode项目的
info=>TARGETS=>HBuilder=>Custom IOS Target Properties
以下配置key是DCLOUD_AD_ID
=打包的目录名和dcloud_appkey
=申请的appKey - 打包,在Xcode的菜单
Product=>Archive
点击,这个的前提是选择运行编译的一栏,选择build的Any iOS Device
- 打包过程,依次
Distribute App
=>Enterprise
=>Next
=>选择证书
参考