<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>ChatGPT | 伪架构师</title>
    <link>/tags/chatgpt/</link>
      <atom:link href="/tags/chatgpt/index.xml" rel="self" type="application/rss+xml" />
    <description>ChatGPT</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Sun, 19 Feb 2023 21:14:35 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>ChatGPT</title>
      <link>/tags/chatgpt/</link>
    </image>
    
    <item>
      <title>用 ChatGPT 写了一点代码</title>
      <link>/post/write-ingress-watcher-with-chatgpt/</link>
      <pubDate>Sun, 19 Feb 2023 21:14:35 +0800</pubDate>
      <guid>/post/write-ingress-watcher-with-chatgpt/</guid>
      <description>

&lt;p&gt;ChatGPT 发布之后，一直在半真半假的用着：有时候写一些代码片段，例如让他用 Python、Rust 分别帮我写一点方法级别的代码；有时候会跟他“探讨”一些问题——是的你没看错，真的是探讨一些问题，例如刚刚我跟他探讨了一下 SRE、DevOps 和平台工程的区别、联系和发展情况。总的说来，如果不求输出成品，那效果还是相当不错的，至少触发灵感是没问题的。&lt;/p&gt;

&lt;p&gt;前些天跟蔡书夸下海口，用 ChatGPT 也能给 PP 写个 Ingress 控制器来，奈何俗务缠身，一直也没能完成，今天抽出两个小时，总算完成了一个 Ingress 监听的原型代码。大体过程讲解一下。&lt;/p&gt;

&lt;p&gt;我的第一个 Prompt：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;我想用循序渐进的方式逐步用 Golang 开发一个 Ingress 控制器，我想到的步骤包括：

1. 创建目录布局 
2. 编写第一个可执行的控制台应用的圆形，并完成构建和测试运行 
3. 在这个原型基础上，加入连接 Kubernetes 集群的能力，同样完成构建和运行 
4. 加入 Watch Ingress 对象的能力。并在 Ingress 发生变化的时候输出提示信息。
首先我们完成第一个步骤，使用 shell 命令创建对应的目录结构。

&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;是的，你没看错，我连目录结构都让他给我创建。ChatGPT 的回复很不错——必须很不错，这个太简单了：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;mkdir -p my-ingress-controller/cmd/my-ingress-controller
mkdir -p my-ingress-controller/pkg/ingress
mkdir -p my-ingress-controller/pkg/kube
touch my-ingress-controller/cmd/my-ingress-controller/main.go
touch my-ingress-controller/pkg/ingress/ingress.go
touch my-ingress-controller/pkg/kube/kube.go
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;并且给出了解释：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;这将创建一个名为 &lt;code&gt;my-ingress-controller&lt;/code&gt; 的目录，并在其中创建 &lt;code&gt;cmd&lt;/code&gt; 和 &lt;code&gt;pkg&lt;/code&gt; 目录，分别用于存放主应用程序和包。此外，我们在 &lt;code&gt;cmd/my-ingress-controller&lt;/code&gt; 目录中创建了 &lt;code&gt;main.go&lt;/code&gt; 文件，用于编写第一个可执行的控制台应用程序的圆形；在 &lt;code&gt;pkg/ingress&lt;/code&gt; 和 &lt;code&gt;pkg/kube&lt;/code&gt; 目录中，分别创建了 &lt;code&gt;ingress.go&lt;/code&gt; 和 &lt;code&gt;kube.go&lt;/code&gt; 文件，用于存放后续的代码。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我照章办事执行之后，当然生成了对应的目录和文件，接下来我给出第二个 Prompt：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;然后完成第二步骤，完成一个可执行的控制台应用的圆形。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ChatGPT 给出了经典的 Hello World 代码，填充了 &lt;code&gt;my-ingress-controller/cmd/my-ingress-controller/main.go&lt;/code&gt;：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;package main

import (
    &amp;quot;fmt&amp;quot;
)

func main() {
    fmt.Println(&amp;quot;Hello, Ingress!&amp;quot;)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接着他解释了代码的作用，提示使用 &lt;code&gt;go build -o my-ingress-controller ./cmd/my-ingress-controller&lt;/code&gt; 命令进行构建。&lt;/p&gt;

&lt;p&gt;对此我的回复是&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;go build 执行失败了，返回信息“go: go.mod file not found in current directory or any parent directory; see &#39;go help modules&#39;”&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ChatGPT 回应大意是：&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;这是因为 Go 1.11 版本后引入了模块（module）的概念，用于解决依赖管理的问题。如果我们的项目使用了 Go 模块，则需要在项目根目录中创建一个 go.mod 文件来记录项目的依赖关系。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go mod init my-ingress-controller&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果你使用的是 Go 1.16 及以上的版本，也可以使用以下命令自动初始化 Go 模块：&lt;code&gt;go mod init&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;照章办事之后，果然构建通过了。&lt;/p&gt;

&lt;p&gt;运行成功后，我们开始连接 Kubernetes，对此我给出的 Prompt 是：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;这一步运行成功之后，我们完成第三个步骤，加入连接 Kubernetes 集群的代码。并再次进行构建和试运行。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ChatGPT 并未含糊，给出了 &lt;code&gt;kube.go&lt;/code&gt; 和 &lt;code&gt;main.go&lt;/code&gt; 的代码：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;// kube.go 两种方法进行连接
package kube

import (
    &amp;quot;k8s.io/client-go/kubernetes&amp;quot;
    &amp;quot;k8s.io/client-go/tools/clientcmd&amp;quot;
    &amp;quot;k8s.io/client-go/rest&amp;quot;
)

func NewClient() (*kubernetes.Clientset, error) {
    config, err := clientcmd.BuildConfigFromFlags(&amp;quot;&amp;quot;, clientcmd.RecommendedHomeFile)
    if err != nil {
        return nil, err
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        return nil, err
    }
    return clientset, nil
}

func InClusterConfig() (*rest.Config, error) {
    return rest.InClusterConfig()
}

//main.go：列出 Namespace

package main

import (
    &amp;quot;fmt&amp;quot;
    &amp;quot;my-ingress-controller/pkg/kube&amp;quot;
)

func main() {
    client, err := kube.NewClient()
    if err != nil {
        fmt.Println(err)
        return
    }
    namespaces, err := client.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{})
    if err != nil {
        fmt.Println(err)
        return
    }
    for _, ns := range namespaces.Items {
        fmt.Println(ns.Name)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;在这个步骤之后，ChatGPT 开始不太灵了，主要出现的问题包括：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client-Go 和 Kubernetes 之间存在对应关系，他对于这方面并没有一个稳定的假设，导致 API 的兼容频频出错&lt;/li&gt;
&lt;li&gt;偶尔会在 Import 方面出现疏漏&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Import 问题基本上来说，贴出构建错误就能解决；而版本问题则需要反复调试和提示才得以解决。&lt;/p&gt;

&lt;p&gt;最后的一个坑是，他给我生成的 Informer 语句如下：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-go&#34;&gt;informerFactory := informers.NewSharedInformerFactoryWithOptions(
    client, 
    0,
    informers.WithNamespace(&amp;quot;default&amp;quot;),
    informers.WithTweakListOptions(func(options *metav1.ListOptions) {
        options.LabelSelector = &amp;quot;app=my-ingress-controller&amp;quot;
    }),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里暗含了对命名空间和标签的要求，导致测试无法通过。在我发现问题发出疑问时，这位很淡定的回答：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;是的，如果要测试 Ingress 资源的监控，可以在创建 Ingress 资源的时候添加一个 &lt;code&gt;app=my-ingress-controller&lt;/code&gt; 的标签，这样就会触发事件并输出日志信息。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&#34;也算总结吧&#34;&gt;也算总结吧&lt;/h2&gt;

&lt;p&gt;所以以后学编程，是不是可以不用费劲加那么多啥微信群了？&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
