<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>log | 伪架构师</title>
    <link>/tags/log/</link>
      <atom:link href="/tags/log/index.xml" rel="self" type="application/rss+xml" />
    <description>log</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Thu, 31 Aug 2017 01:35:22 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>log</title>
      <link>/tags/log/</link>
    </image>
    
    <item>
      <title>Kubernetes 的审计日志和采集</title>
      <link>/post/auditlog-in-k8s/</link>
      <pubDate>Thu, 31 Aug 2017 01:35:22 +0800</pubDate>
      <guid>/post/auditlog-in-k8s/</guid>
      <description>

&lt;h2 id=&#34;基础操作&#34;&gt;基础操作&lt;/h2&gt;

&lt;p&gt;一个正常运行的 Kubernetes 集群，除了利用访问控制对集群操作的许可进行限制之外，对于操作过程的跟踪审计也是比不可少的，围绕不同的实体，例如用户、节点以及各种工作负载进行观测是很有必要的。Kubernetes 的 API Server 提供了审计日志支持，利用审计日志的方式对系统内的操作进行记录，这里我们可以沿用推荐的 Elastic Search + Fluentd 对审计日志进行采集存储，最终使用 Kibana 或者其他支持 ES 查询的工具对关键资源或用户进行访问跟踪。&lt;/p&gt;

&lt;p&gt;首先要启用 API Server 的审计功能。Kubernetes 提供了四个基础参数来定义审计功能：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;audit-log-path&lt;/strong&gt; 启用审计日志，并将日志内容写入指定文件，“-” 代表 stdout。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;audit-log-maxage&lt;/strong&gt; 日志文件的最大保存天数，根据文件名中的日期进行确定。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;audit-log-maxbackup&lt;/strong&gt; 最多保存日志文件的数量。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;audit-log-maxsize&lt;/strong&gt; 最大文件尺寸，超过尺寸会被翻转。单位是 MB，缺省为 100MB。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;例如：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;--audit-log-path=/var/log/kubernetes/kubernetes.audit \
--audit-log-maxage=7 \
--audit-log-maxbackup=4 \
--audit-log-maxsize=10
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在 Kubernetes API Server 的启动参数中加入这些开关之后，重新启动服务。&lt;/p&gt;

&lt;p&gt;这时我们就可以看到文件&lt;code&gt;/var/log/kubernetes/kubernetes.audit&lt;/code&gt;已经生成。利用 tail 命令看看他的结构和内容，例如请求内容是这样的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;2017-08-30T16:28:35.485818099+08:00 AUDIT: id=&amp;quot;ebc47b7b-c4fe-4a9a-861c-d9686903cec4&amp;quot; ip=&amp;quot;127.0.0.1&amp;quot; method=&amp;quot;GET&amp;quot; user=&amp;quot;system:apiserver&amp;quot; groups=&amp;quot;\&amp;quot;system:masters\&amp;quot;&amp;quot; as=&amp;quot;&amp;lt;self&amp;gt;&amp;quot; asgroups=&amp;quot;&amp;lt;lookup&amp;gt;&amp;quot; namespace=&amp;quot;&amp;lt;none&amp;gt;&amp;quot; uri=&amp;quot;/apis/admissionregistration.k8s.io/v1alpha1/initializerconfigurations&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;而响应内容格式如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;2017-08-30T16:28:35.486131325+08:00 AUDIT: id=&amp;quot;ebc47b7b-c4fe-4a9a-861c-d9686903cec4&amp;quot; response=&amp;quot;404&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;我们本文中暂时只对请求内容进行进一步解析，响应内容可以通过加入第二格式的方式进行采集。内容中的&lt;code&gt;id&lt;/code&gt;字段，可以看作是会话 id，用于连接请求和响应。&lt;/p&gt;

&lt;p&gt;根据上述文本内容，可以开始 Fluentd 文件的编写。请求和响应的内容都很规则，简单的正则表达式即可完成解析，例如我写的是这样的：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;&amp;lt;source&amp;gt;
  type tail
  format /^(?&amp;lt;time&amp;gt;\d.*?)\s+(?&amp;lt;action&amp;gt;\w+).\s+id=\&amp;quot;(?&amp;lt;id&amp;gt;.*?)\&amp;quot;\s+ip=\&amp;quot;(?&amp;lt;ip&amp;gt;.*?)\&amp;quot;\s+method=\&amp;quot;(?&amp;lt;method&amp;gt;.*?)\&amp;quot;\s+user=\&amp;quot;(?&amp;lt;user&amp;gt;.*?)\&amp;quot;\s+groups=(?&amp;lt;groups&amp;gt;.*?)\s+as=\&amp;quot;(?&amp;lt;as&amp;gt;.*?)\&amp;quot;\s+asgroups=\&amp;quot;(?&amp;lt;asgroups&amp;gt;.*?)\&amp;quot;\s+namespace=\&amp;quot;(?&amp;lt;namespace&amp;gt;.*?)\&amp;quot;\s+uri=\&amp;quot;(?&amp;lt;uri&amp;gt;.*?)\&amp;quot;$/
  path /var/log/kubernetes/kubernetes.audit
  pos_file /var/log/audit.pos
  time_format %Y-%m-%dT%H:%M:%S.%N%z
  tag audit.response
&amp;lt;/source&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将这一部分内容加入到 Fluentd 配置之中去，启动抓取。日志入库之后，我们就可以对指定用户或者资源进行查询，获知他的黑历史了，例如我们要查找用户&lt;code&gt;admin&lt;/code&gt;的操作历史：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;quot;query&amp;quot;: {
    &amp;quot;match&amp;quot;: {
      &amp;quot;user&amp;quot;: {
        &amp;quot;query&amp;quot;: &amp;quot;admin&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;phrase&amp;quot;
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在 Kibana 中执行查询，会看到类似内容（如果所在集群没有该用户，可以替换为 &lt;code&gt;system:apiserver&lt;/code&gt;等内置用户进行测试）：&lt;/p&gt;

&lt;p&gt;利用解析出的各个字段，可以比较清楚的看到什么人，在什么时间，对什么对象进行了什么操作。&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;images/audit-screenshot.jpg&#34; alt=&#34;screenshot&#34; /&gt;&lt;/p&gt;

&lt;h2 id=&#34;高级审计&#34;&gt;高级审计&lt;/h2&gt;

&lt;p&gt;在 Kubernetes 1.7 中新增了 Advanced audit 特性（Alpha），可以对审计内容、以及后续处理进行定义。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;首先加入了审计策略的支持，可以使用行为，动作等条件进行限制，过滤掉无需考虑的审计内容。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;存储后端在日志之外，还增加了 Web Hook 的支持，可以直接将审计内容发布到指定的 Web 服务中。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>在 Kubernetes 中使用 Fluent Bit 进行日志采集</title>
      <link>/post/fluentbit-in-k8s/</link>
      <pubDate>Mon, 10 Jul 2017 08:51:52 +0800</pubDate>
      <guid>/post/fluentbit-in-k8s/</guid>
      <description>&lt;p&gt;Fluent Bit 和 Fluentd 一样，是 Treasure Data 资助的采集工具，二者对比如下：&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Fluentd&lt;/th&gt;
&lt;th&gt;FluentBit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;范围&lt;/td&gt;
&lt;td&gt;服务器&lt;/td&gt;
&lt;td&gt;嵌入设备和 IoT 设备&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;内存&lt;/td&gt;
&lt;td&gt;约 20 MB&lt;/td&gt;
&lt;td&gt;约 150 KB&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;语言&lt;/td&gt;
&lt;td&gt;C 和 Ruby&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;性能&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;依赖&lt;/td&gt;
&lt;td&gt;以 Ruby Gem 构建，依赖一系列的 Gem&lt;/td&gt;
&lt;td&gt;零依赖，可能有些插件会有依赖。&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;插件&lt;/td&gt;
&lt;td&gt;超过三百个&lt;/td&gt;
&lt;td&gt;目前15个左右&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;授权&lt;/td&gt;
&lt;td&gt;Apache License v2.0&lt;/td&gt;
&lt;td&gt;Apache License v2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;从上表可以看出，Fluentd 具有众多插件，随之而来的是很好的弹性。而 Fluent Bit 则更适用于嵌入设备等资源受限的场景。另外二者并非互斥关系，Fluent Bit 提供了输出插件，可以把数据发给 Fluentd，因此他们可以在系统中作为独立服务互相协作。&lt;/p&gt;

&lt;p&gt;Fluent Bit 也提供了 Kubernetes Filter 插件，用于将采集到的日志结合对 Kubernetes API 的查询，为日志加入 Kubernetes 的相关数据，例如 Pod 信息、容器信息、命名空间以及标签和注解等内容。&lt;/p&gt;

&lt;p&gt;仅就此来说，Fluent Bit 是可以替代 Kubernetes 缺省推荐的 Fluentd 进行日志采集工作的，经过笔者测试，可以直接使用他替代原有的 Fluentd，使用 DaemonSet 运行，结合 Elastic Search 进行日志归集工作。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;详情参见：&lt;a href=&#34;http://fluentbit.io/documentation/0.11/filter/kubernetes.html&#34; target=&#34;_blank&#34;&gt;http://fluentbit.io/documentation/0.11/filter/kubernetes.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;简单的使用如下命令就可以运行：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    kubectl create -f https://raw.githubusercontent.com/fluent/fluent-bit-kubernetes-daemonset/master/fluent-bit-daemonset-elasticsearch.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这一 YAML 文件中的镜像版本为 0.11，具体版本更新可以到 Docker Hub 进行查询，其中包含的缺省 elasticsearch 地址为 elasticsearch-logging，端口为 9200，如上配置如果不符，可以下载文件自行修改运行。&lt;/p&gt;

&lt;p&gt;另外目前 RBAC 的访问控制模式已经成为缺省，在启用了 RBAC 模式的集群中，该 Pod 的运行是无法成功的，具体表现是日志中出现无法获取 Pod 元数据的信息，这是因为缺省情况下，这一 YAML 中使用的是 &lt;code&gt;kube-system&lt;/code&gt; 中的 &lt;code&gt;default&lt;/code&gt;  Service Account，这一服务账号并不具备获取 Pod 信息的授权，要成功运行，就必须按照 RBAC 的规矩，让 Fluent Bit 的 Service Account 能够获取 Pod 信息，可以用如下方式来解决：&lt;/p&gt;

&lt;p&gt;首先为 Fluent bit 创建专门的 Service Account：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    kubectl create sa logging -n kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;然后为日志收集器创建角色，让该角色可以读取 Pod 信息。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: pod-reader
rules:
- apiGroups: [&amp;quot;&amp;quot;]
  resources: [&amp;quot;pods&amp;quot;]
  verbs: [&amp;quot;get&amp;quot;, &amp;quot;watch&amp;quot;, &amp;quot;list&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来创建 ClusterRoleBinding，把新建的角色和 Service Account 绑定在一起：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: read-pods-global
subjects:
- kind: ServiceAccount
  name: logging
  namespace: kube-system
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最后在 Fluent Bit 的 yaml 中加入 Service Account 的指派：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;# 省略若干
spec:
  template:
    metadata:
      labels:
        k8s-app: fluent-bit-logging
        version: v1
        kubernetes.io/cluster-service: &amp;quot;true&amp;quot;
    spec:
      serviceAccountName: logging
# 省略若干
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;经过这一番折腾之后，Fluent Bit 就可以在开启 RBAC 的 1.&lt;sup&gt;6&lt;/sup&gt;&amp;frasl;&lt;sub&gt;1&lt;/sub&gt;.7 集群上运行了。打开相应的 Kibana 页面，会看到和标配 Fluentd 一致的日志搜集结果。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;好吧，今天讲的其实是 RBAC。&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
    <item>
      <title>简单的 Kubernetes Pod 日志查看工具 Kubetail</title>
      <link>/post/introducing-kubetail/</link>
      <pubDate>Sat, 11 Mar 2017 01:47:52 +0800</pubDate>
      <guid>/post/introducing-kubetail/</guid>
      <description>

&lt;p&gt;​传统来说，Kubernetes 环境下的日志都是靠 FluentD + ElasticSearch + Kibana 的组合实现的，这一组合的功能和强大，所以成为一个事实标准来使用，但是在一些比较简陋的测试集群中，或者不具备浏览器条件的自动化/控制台环境下，归并多个 Pod 的日志进行集中的查看和处理还是很有用的。&lt;/p&gt;

&lt;p&gt;Kubetail 是一个 Bash 脚本，功能类似 &lt;code&gt;kubectl -f logs pod-name&lt;/code&gt;，但是不同的是，他同时对多个 Pod 工作，并把日志合并到一个流中。&lt;/p&gt;

&lt;p&gt;项目网址：&lt;a href=&#34;https://github.com/johanhaleby/kubetail&#34; target=&#34;_blank&#34;&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;

&lt;p&gt;只是个脚本，可以直接下载安装。&lt;/p&gt;

&lt;h3 id=&#34;mac-用户&#34;&gt;Mac 用户：&lt;/h3&gt;

&lt;p&gt;brew tap johanhaleby/kubetail &amp;amp;&amp;amp; brew install kubetail&lt;/p&gt;

&lt;h3 id=&#34;使用&#34;&gt;使用&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;kubetail [-h] [-c] [-n] [-t] [-l] [-s] pod-name-prefix

-c：多容器 Pod 中，指定容器名称
-t：指定 kube config 文件中的 context
-l：标签过滤器，使用 -l 参数之后，会忽略后面的 pod 名称
-n：namespace
-s：只返回一个相对时间之后的日志，例如 5s，2m 或者 3h，缺省是 10s
-b：是否使用 line-buffered。缺省为 false
-k：输出的着色
pod：只给 pod 名称上色
line：整行上色（缺省）
false：不上色
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    
  </channel>
</rss>
