ChatGPTでKubernetesのマニフェストファイルを作成してみる

# この記事の概要
2023年3月15日に言語モデル「GPT-4」が公開され、さらに話題となっている ChatGPT ですが、様々な領域で驚きの性能を発揮しています。IT・プログラミングの領域でもChatGPTの活用は進んでおり、[ぷよぷよを作らせる](https://zenn.dev/corocn/articles/b4c473ed779935)といったことも可能になっています。

この記事では、KubernetesのマニフェストファイルをChatGPTでどの程度作成できるのかを確認してみたいと思います（これを題材に選んだのは、マニフェストファイルの書き方をすぐに忘れてしまうためです）。


# 前提
- 言語モデル　：　GPT-4
- 実施日　：　 2023年3月18日


# ConfigMapを生成する
まずは簡単なものとして、ConfigMapを生成してもらいます。ChatGPTで以下を与えます。

>Kubernetesで以下のキー・値を持つConfigMapのYAMLファイルを作成してください。
>
>key1 = value1
>key2 = value2

これに対するChatGPTの回答は以下になります。

-------------------------------------------------------------------------------

> 以下は、指定されたキーと値を持つConfigMapのYAMLファイルです。

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
data:
  key1: value1
  key2: value2
```

> このYAMLファイルは、my-configmapという名前のConfigMapを作成します。dataフィールドには、指定されたキーと値のペアが含まれています。このファイルを適切なファイル名（例: my-configmap.yaml）で保存し、kubectl apply -f my-configmap.yamlを実行してConfigMapをKubernetesクラスタに適用できます。

-------------------------------------------------------------------------------

指示された通りに、`my-configmap.yaml`を作成し、Kubernetesに対して適用してみます。以下の通り、特に問題無くConfigMapを作成することができました。

```bash
❯ kubectl apply -f my-configmap.yaml 
configmap/my-configmap created

❯ kubectl describe configmap my-configmap               
Name:         my-configmap
Namespace:    sample
Labels:       <none>
Annotations:  <none>

Data
====
key2:
----
value2
key1:
----
value1

BinaryData
====

Events:  <none>
```



# Secretを生成する
今度は同じキー・値を持つSecretを作成してみます。ChatGPTで以下を与えます。

> Kubernetesで以下のキー・値を持つSecretのYAMLファイルを作成してください。
> 
> key1 = value1
> key2 = value2

これに対するChatGPTの回答は以下になります。

-------------------------------------------------------------------------------
> Kubernetes Secretを作成するためのYAMLファイルは次のようになります。キーと値のペアはbase64でエンコードする必要があります。
> まず、base64でエンコードします:

```bash
echo -n 'value1' | base64
echo -n 'value2' | base64
```

> これにより、エンコードされた値を取得できます。次に、YAMLファイルを作成します:

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  key1: dmFsdWUx # base64 encoded value of 'value1'
  key2: dmFsdWUy # base64 encoded value of 'value2'
```


> 上記のYAMLファイルをmy-secret.yamlとして保存し、kubectl apply -f my-secret.yamlコマンドを使用してKubernetesクラスタにSecretを作成します。
-------------------------------------------------------------------------------

Secretの場合、値部分についてBase64エンコードが必要となりますが、ChatGPTの回答ではBase64エンコードについても言及されており、生成されたマニフェストファイルもエンコードされた状態で出力されています。


# Deployment、Serviceを生成する
もう少し難しい例として、DeploymentとServiceを生成してみます。ここでは、nginxの最新版をデプロイするDeployment、および、それをNodePort Serviceで公開するという内容を試してみます。また、DeploymentのPodでは、リソース上限（Resource Limits）と初期リクエスト（Resource Requests）を指定することにします。

以下をChatGPTに与えます。

> Kubernetesに適用する以下のYAMLファイルを作成してください。
> 
> ・nginxの最新版をデプロイするDeploymentを作成する
> ・リソース上限として、CPU：100m、メモリ：300MBを設定する
> ・リソースの初期リクエストとして、CPU：50m、メモリ：100MBを設定する


これに対するChatGPTの回答は以下になります。

-------------------------------------------------------------------------------
> 以下のYAMLファイルは、指定された条件に従って、nginxの最新版をデプロイするDeploymentを作成し、リソース制限と初期リクエストを設定します。

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 100m
            memory: 300Mi
          requests:
            cpu: 50m
            memory: 100Mi
```

> このYAMLファイルを使用して、KubernetesクラスターにDeploymentを作成できます。ファイルを適切な名前で保存し（例: nginx-deployment.yaml）、kubectl apply -f nginx-deployment.yamlコマンドを実行してDeploymentを適用してください。
-------------------------------------------------------------------------------

特に問題の無い内容でマニフェストファイルが生成されました。メモリの指定で300MB、100MBと指定したところは、きちんと300Mi、100Miに変えて生成されています。

それではこのマニフェストファイルを指示通りに `kubectl apply` し、その結果を確認します。Deploymentは正常に作成され、Podも問題なく`Running`状態となっています。コンテナイメージとして `nginx:latest` が指定されており、Resource Limits、Resource Requestsの指定も問題ありません。


```bash
❯ kubectl get deployment
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           104s

❯ kubectl describe deployment nginx-deployment
Name:                   nginx-deployment
Namespace:              sample
(中略)
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:      nginx:latest
    Port:       80/TCP
    Host Port:  0/TCP
    Limits:
      cpu:     100m
      memory:  300Mi
    Requests:
      cpu:        50m
      memory:     100Mi
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>

❯ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-787cc97454-l4gm4   1/1     Running   0          2m8s
```

続けて、Serviceのマニフェストファイルを生成するため、**同じチャット内で**以下を与えます。

> このPodにアクセスするためのNodePort ServiceのYAMLを作成してください

これに対するChatGPTの回答は以下になります。

-------------------------------------------------------------------------------
> 以下のYAMLファイルは、指定された条件に従って、NodePort Serviceを作成します。これにより、nginxデプロイメントのPodにアクセスできるようになります。

```yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080
  type: NodePort
```

> このYAMLファイルを使用して、KubernetesクラスターにServiceを作成できます。ファイルを適切な名前で保存し（例: nginx-service.yaml）、kubectl apply -f nginx-service.yamlコマンドを実行してServiceを適用してください。
> 
> 適用後、kubectl get servicesコマンドを実行して、Serviceが正しく作成されたことを確認できます。さらに、NodePort (30080) を使用して、クラスター内の任意のノードからnginx Podにアクセスできます。
-------------------------------------------------------------------------------

指示通りに `kubectl apply` し、その結果を確認してみます。正常にNodePort Serviceが30080ポートで生成されています。

```bash
❯ kubectl apply -f nginx-service.yaml
service/nginx-service created

❯ kubectl get service
NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
nginx-service   NodePort   10.43.28.26   <none>        80:30080/TCP   6s
```

それでは上記のポートで公開されたnginxにアクセスしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e0f544be-4fc0-a5ae-76b4-ebb576b074c1.png)

nginxに無事にアクセスすることができました。


# まとめと課題
以上の通り、ConfigMap、Secretといった簡単なものだけでなく、リソース条件を指定したDeploymentといったある程度の複雑さを持ったマニフェストファイルも問題無く生成できており、ChatGPTの性能の高さをあらためて感じました。

ただ、今回の記事には含めていませんが、ConfigMapを生成した後、同じチャット内で「同じキー・値を持つSecretのYAMLファイルを作成してください。」という指示をしたところ、Base64エンコードをキー・値の全体（`key1 :  value1`）に対して実施してしまいました。今回のように何が生成されるべきかの答えを知っている場合は間違いに気がつけるのですが、そうでない場合は生成された内容が正しいかどうかの判断ができず、少し使いどころが難しいかもしれません。
（なお、その後さらに同じチャット内で「base64エンコードはキーに対しては実施せず、値に対してのみ実施するべきです。値にのみbase64エンコードを適用してください。」と指示したところ、正しい内容のマニフェストファイルを生成してくれました）