<?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>Kubernetes on 翟志军 Jack Zhai</title>
    <link>https://showme.codes/tags/kubernetes/</link>
    <description>Recent content in Kubernetes 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/kubernetes/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Jenkins kubernetes插件的原理</title>
      <link>https://showme.codes/zh-cn/2024-02-26-jenkins-kubernetes-plugin/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://showme.codes/zh-cn/2024-02-26-jenkins-kubernetes-plugin/</guid>
      <description>&lt;h2 id=&#34;如何使用&#34;&gt;如何使用&lt;/h2&gt;
&lt;p&gt;使用Kubernetes插件时，我们需要做三件事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根据官方文档，在Jenkins上加入kubernetes配置。&lt;/li&gt;
&lt;li&gt;在Jenkinsfile中加入kubernetes agent的申明。&lt;/li&gt;
&lt;li&gt;指定容器执行你的业务脚本。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;关于第2点，kubernetes agent的申明又有两种方式。一种是脚本式的，代码样例如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;podTemplate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;containers:&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;…&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;node&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;POD_LABEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Run shell&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mycontainer&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;echo hello world&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}}}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;一种是申明式，代码样例如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-groovy&#34; data-lang=&#34;groovy&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;pipeline&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;stages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Run maven&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;agent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;kubernetes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                kind: Pod
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                metadata:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                  labels:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    app: jenkins-agent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                spec:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                  containers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                  - name: maven
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    image: maven:alpine
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    command:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    - cat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    tty: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                  - name: busybox
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    image: busybox
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    command:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    - cat
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                    tty: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;                &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;steps&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;maven&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;n&#34;&gt;sh&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;mvn -version&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}}}}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;笔者推荐使用申明式。yaml配置部分看起来并不优雅，这是另一个话题。咱们今后再讲。&lt;/p&gt;</description>
    </item>
    <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>
  </channel>
</rss>
