<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>云原生 on 翟志军 Jack Zhai</title>
    <link>https://showme.codes/tags/%E4%BA%91%E5%8E%9F%E7%94%9F/</link>
    <description>Recent content in 云原生 on 翟志军 Jack Zhai</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <copyright>showme.codes</copyright>
    <lastBuildDate>Mon, 26 Feb 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://showme.codes/tags/%E4%BA%91%E5%8E%9F%E7%94%9F/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>K8s工程化：K8s中的Java应用出现OOM后怎么办？</title>
      <link>https://showme.codes/zh-cn/2024-2-26-jvm-oom-kubernetes/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-2-26-jvm-oom-kubernetes/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;完整代码在文末&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;背景&#34;&gt;背景&lt;/h3&gt;
&lt;p&gt;前段时间，线上系统出现了两次持续时间比较长的事故。这两次事故暴露我在某些方面的不足。同时，也意识到在SRE这个领域，经验的重要性。&lt;/p&gt;
&lt;p&gt;事故过程中，我们发现大量的FullGC。当时，我们想到了要dump内存出来分析，可惜发现没有加&lt;code&gt;-XX:HeapDumpPath&lt;/code&gt;参数。同时，我们也发现，如果dump出来了，我们也没法拿到dump出来的文件。因为我们的应用是跑在K8s中的。&lt;/p&gt;
&lt;h3 id=&#34;方案调研&#34;&gt;方案调研&lt;/h3&gt;
&lt;p&gt;经复盘，我们得到一个action：在Java应用出现OOM时，将内存dump出来，并持久化，并且方便分析。&lt;/p&gt;
&lt;p&gt;这个action可以细分为两个任务：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;OOM时，dump内存出来；&lt;/li&gt;
&lt;li&gt;提供一种途径方便分析。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;经过权衡，任务2的优先级是可以降低的。puvad只要把任务1做好就可以。所以，这两个任务最终变成：在Java应用出现OOM时，将内存dump到NAS中。&lt;/p&gt;
&lt;p&gt;笔者在网上搜索一通，看到的方案基本就是启动一个sidecar容器，与应用共享一个目录。然后监控这个目录，发现内容就上传到s3这类对象存储中。&lt;/p&gt;
&lt;p&gt;这种方案的问题在于：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;sidecar在传输过程，有出现问题的风险；&lt;/li&gt;
&lt;li&gt;为了OOM这个小概率事件启动一个sidecar，资源有点浪费。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;个人觉得，Java应用的Pod应该只负责将OOM时的内存dump到NAS即可，其它事情应该由其它Pod完成。&lt;/p&gt;
&lt;h3 id=&#34;具体实现&#34;&gt;具体实现&lt;/h3&gt;
&lt;p&gt;以下方案是基于Helm自动化部署。如果你使用的是其它自动化部署工具，思路大体相同。&lt;/p&gt;
&lt;h4 id=&#34;准备nfs服务&#34;&gt;准备NFS服务&lt;/h4&gt;
&lt;p&gt;这部分不是本文范畴。&lt;/p&gt;
&lt;h4 id=&#34;java应用启动时参数配置&#34;&gt;Java应用启动时参数配置&lt;/h4&gt;
&lt;p&gt;在Dockerfile中必须将变量$JAVA_OPTS加入到启动参数中。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;FROM openjdk:11.0.12-jre-buster
COPY target/app.jar /app.jar
CMD java -jar $JAVA_OPTS /app.jar
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;加入initcontainers&#34;&gt;加入InitContainers&lt;/h4&gt;
&lt;p&gt;作用：创建符合指定规则的Dump目录（注意DUMP_FOLDER变量的定义）。如下代码，在init容器启动后，它会创建目录：/nfs/dump/default/jvm-oom-example/10.233.66.38 。在应用出现OOM，内存文件会被dump在此目录下。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;initContainers:
- name: init
  image: registry.cn-shenzhen.aliyuncs.com/aliacs-app-catalog/busybox:1.30.1
  command: [&amp;#39;sh&amp;#39;, &amp;#39;-c&amp;#39;, &amp;#39;echo $DUMP_FOLDER;mkdir -p $DUMP_FOLDER&amp;#39;]
  {{- with .Values.volumeMounts }}
  volumeMounts:
  {{- toYaml . | nindent 12 }}
  {{- end }}
  env:
  - name: MY_NODE_NAME
      valueFrom:
      fieldRef:
          fieldPath: spec.nodeName
  - name: MY_POD_NAME
      valueFrom:
      fieldRef:
          fieldPath: metadata.name
  - name: MY_POD_NAMESPACE
      valueFrom:
      fieldRef:
          fieldPath: metadata.namespace
  - name: MY_POD_IP
      valueFrom:
      fieldRef:
          fieldPath: status.podIP
  - name: DUMP_FOLDER
      value: &amp;#34;/nfs/dump/$(MY_POD_NAMESPACE)/{{ include &amp;#34;app.fullname&amp;#34; . }}/$(MY_POD_IP)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;配置应用容器&#34;&gt;配置应用容器&lt;/h4&gt;
&lt;p&gt;我们要做的，其实就是设置JAVA_OPTS环境变量。这里要注意的是JAVA_OPTS可以由三部分组成的：&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes包管理器Helm的本质</title>
      <link>https://showme.codes/zh-cn/2024-2-26-theory-of-helm/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-2-26-theory-of-helm/</guid>
      <description>了解Helm的本质后，学习其它工具就很容易了</description>
    </item>
    <item>
      <title>SRE-DevOps不得不懂的：Prometheus的配置工程化</title>
      <link>https://showme.codes/zh-cn/2024-2-26-prometheus-engineering/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-2-26-prometheus-engineering/</guid>
      <description>优雅地管理Prometheus的配置</description>
    </item>
    <item>
      <title>云原生部署之Helm最佳实践</title>
      <link>https://showme.codes/zh-cn/2024-2-26-helm-best-practice/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-2-26-helm-best-practice/</guid>
      <description>Helm部署实践总结</description>
    </item>
    <item>
      <title>可落地的云原生应用规范</title>
      <link>https://showme.codes/zh-cn/2024-2-26-cloud-native-specification/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-2-26-cloud-native-specification/</guid>
      <description>这个规范可以让你的云原生实践更顺畅</description>
    </item>
  </channel>
</rss>
