🕸️

コンテナ専用OS Talos Linuxを用いたKubernetesクラスタ(構築編)

2024/06/30に公開

この記事の概要

本記事ではコンテナ専用OSの1つであるTalos Linuxを使用して、Kubernetesクラスタを構築します。
個人的に何かしらのコンテナ専用OSを触ってみたいと思い調べてみたところ、Talos Linuxというディストリビューションを見つけ面白そうだと思ったのですが、日本語でまとまっている記事がなさそうだったので記事にしました。

Talos Linuxとは

Talos Linuxとは、Kubernetesでの使用に特化したLinuxディストリビューションです。

https://www.talos.dev/
https://www.siderolabs.com/platform/talos-os-for-kubernetes/

Kubernetesクラスタを構築する際、Nodeに使用するLinuxのディストリビューションの選択はユーザーに委ねられます。一般的にはUbuntuなどのディストリビューションが使用されることが多い印象ですが、近年ではコンテナを動かすことに特化したLinuxディストリビューション(コンテナ専用OS)が存在し、それらが利用されるケースもあります。

例えばAWSではBottlerocket、Google CloudではContainer-Optimized OSというコンテナ専用OSが提供されており、利用することができます。

コンテナ専用OSの特徴はディストリビューションによって異なりますが、大きく以下の2点にまとめられるのではないかと思います。

  • 運用性の向上
    • コンテナを実行するための環境があらかじめセットアップされており、環境構築や更新が容易
  • セキュリティレベルの向上
    • 汎用的なディストリビューションと比べて含まれるコンポーネントがコンテナの実行に必要なものに特化しているため、アタックサーフェスの削減に繋がる

本記事で紹介するTalos Linuxもこのようなコンテナ専用OSの1つで、オープンソースとして公開されています。
また、CNCF Landscapeでは、Certified Kubernetes Installerとして登録されています。

因みにTalos Linuxという名前はギリシャ神話に登場する自動人形タロスに由来しているそうです。

https://www.talos.dev/v1.7/learn-more/faqs/#why-the-name-talos

Talos Linuxの特徴

Talos Linux公式ドキュメントの記載内容を要約すると、以下のような特徴があるようです。
一通り眺めた感じだと、かなりセキュリティを意識した作りになっているように見えます。

  • Kubernetesでの利用に特化
    • Nodeに必要なコンポーネントが自動的にインストールされるため、手動でのインストール作業が不要
    • 最新のKubernetesバージョンに対応している
  • コンテナを動作させるのに必要最小限のものだけを含んでいる
    • ShellやSSHを含んでおらず、操作はAPI経由で行う(可能な操作は公開されているAPIで定義されたものに限定される)
    • NIST Special Publication 800-190における推奨事項に準拠(ホストOSに対する対策)
  • あらかじめセキュリティを意識した設定が施されている
  • Nodeの状態をImmutableに保つことができる(Nodeがステートフルになることを防ぐ)
    • rootfsがRead-Onlyでマウントされている
    • SquashFSと呼ばれるファイルシステムを用いてメモリ上で実行される
    • データをディスク上に永続化しない

以下のページにTalos Linuxの思想がまとまっているので詳細が気になる場合はこちらも参照してください。

https://www.talos.dev/v1.7/learn-more/philosophy/

Talos Linuxを用いたKubernetesクラスタの構築

ここからはTalos Linuxを用いてKubernetesクラスタを構築していきます。基本的には公式ドキュメントに沿って進めていきます。

https://www.talos.dev/v1.7/introduction/getting-started/

今回構築するKubernetesクラスタの構成は以下の通りとします。
あらかじめ各サーバーに対しては、Kubernetesクラスタの構築作業を行うサーバー(この後解説するtalosctlコマンドを実行するサーバー)から名前解決を行えるようにしています。

Host IP Role
k8s-talos-cp01 192.168.2.140 Control Plane
k8s-talos-node01 192.168.2.141 Node
k8s-talos-node02 192.168.2.142 Node

talosctlのインストール

はじめにtalosctlというCLIツールをインストールします。
Talos LinuxにはSSHやBashが含まれていないため、通常のLinuxディストリビューションのようにSSHで接続して対話的な操作を行うことができません。その代わりにAPIが公開されているため、talosctlを用いてAPI経由で操作を行うことになります。

https://www.talos.dev/v1.7/talos-guides/install/talosctl/

インストール方法はいくつか用意されていますが、インストールスクリプトを実行するのが一番手っ取り早いでしょう。

$ curl -sL https://talos.dev/install | sh

$ talosctl version
Client:
	Tag:         v1.7.5
	SHA:         47731624
	Built:       
	Go version:  go1.22.4
	OS/Arch:     linux/amd64
Server:
error constructing client: failed to determine endpoints

サーバーのセットアップ

Talos Linuxのインストール方法は様々ありますが、ここではISOを用いてインストールする最も基本的な方法を採用します。
https://www.talos.dev/v1.7/talos-guides/install/

Talos Linuxを各サーバーにインストールするためのISOを取得します。ISOはGitHubのReleaseとして公開されているため、任意のバージョンをダウンロードします。
今回は執筆時点での最新バージョンであるv1.7.5を使用しました。
因みに今回筆者は自宅の仮想サーバー(AMD64アーキテクチャ)を使用するため、こちらのISOを使用しました。

https://github.com/siderolabs/talos/releases

ISOをダウンロードしてみると、サイズは約93MBでした。筆者がよく使用するUbuntu 22.04のISOが1.47GB程度であることを踏まえると、かなりサイズが小さいことが分かります。

ISOのダウンロードが完了したら、通常Linuxサーバーを構築する時と同じようにISOをドライブにセットし、サーバーを起動します。
起動が完了すると、次のようなコンソールが表示されます。

IPアドレスはDHCPで自動的に設定されますが、変更したい場合はF3キーを押下して変更することもできます。ホスト名もここで設定しておきます。


コンソールでの設定はこれで完了です。
以降はtalosctlを用いたAPI経由での操作になります。

machine configとtalosconfigの作成

まずはサーバーの設定を定義するためのmachine configと、Talos Linuxをtalosctlから操作する際に用いる認証情報が記載されたtalosconfigを作成します。
<Cluster Name>には、任意のKubernetesクラスタ名を指定します。今回はk8s-talos-clusterとしました。
また<Kubernetes Endpoint>には、これから構築するKubernetesクラスタのAPIエンドポイントに当たる情報を指定します。
今回構築するKubernetesクラスタのControl Planeはk8s-talos-cp01の1台のみなので、<Kubernetes Endpoint>にはk8s-talos-cp01を指定しました。
複数のControl Planeを用いた構成とする場合は、それらを束ねるLoadBalancerのホスト名やVIPを指定することになります。
※ホスト名を指定する場合は別途名前解決ができる状態にしておく必要があります。IPアドレス(今回の場合192.168.2.140)を指定しても問題ありません。

$ talosctl gen config `<Cluster Name>` https://<Kubernetes Endpoint>:6443

コマンドの実行が完了すると、次の3つのファイルが生成されます。

  • talosconfig
    • セットアップ後の各サーバーに対してtalosctlでAPIアクセスする時に使用する認証情報
  • controlplane.yaml
    • Control Planeとして使用するサーバーをセットアップするための設定
  • worker.yaml
    • Nodeとして使用するサーバーをセットアップするための設定

controlplane.yamlworker.yamlmachine configに該当し、サーバーの設定情報が定義されています。これから構築するKubernetesクラスタに関する設定情報もこの中に記載されています。
全ては解説しませんが、例えばcontrolplane.yaml.cluster.apiServerというフィールドでは、kube-apiserverに関する設定が定義されていることが確認できます。
その他にもcontrolplane.yamlではkube-controller-managerkube-schedulerなど、KubernetesクラスタのControl Planeに属するコンポーネントの設定が定義されています。
また、controlplane.yamlworker.yamlそれぞれの.machine.kubeletというフィールドでは、kubeletに関する設定が定義されていたり、.cluster.networkというフィールドでは構築するKubernetesクラスタのネットワークに関する設定が定義されていることが確認できます。

machine configの詳細は以下を参照してください。
https://www.talos.dev/v1.7/reference/configuration/v1alpha1/config/

中でも筆者が興味深いと感じたのは、デフォルトでKubernetesのセキュリティに関する以下2点の機能が有効化されている点でした。
ここからも、Talos Linuxがセキュリティを意識した作りになっていることが垣間見えます。

PodSecurity Admission

KubernetesにはPodSecurity Admissionと呼ばれるBuilt-inのポリシー制御機能が存在します。
この機能が有効になっていると、Pod Security Standardsで定義されたポリシーに準拠しないPodのデプロイが禁止されます。

PodSecurity Admissionについては過去の登壇で使用した資料がありますのであわせてご覧ください。

通常PodSecurity AdmissionではNamespace単位で適用するポリシーを設定しますが、kube-apiserverのAdmissionConfiguration(Admission Controllerの設定)として、Kubernetesクラスタ全体に対してポリシーを設定することもできます。
Talos Linuxではcontrolplane.yamlに、PodSecurity Admissionに関するAdmissionConfigurationに相当する設定が定義されており、デフォルトではクラスタ全体に対してPod Security StandardsのBaselineポリシーに違反する特権コンテナを含むPodなどのデプロイを禁止する設定が適用されるようになっています。

controlplane.yaml

    # API server specific configuration options.
    apiServer:
        ...
        # Configure the API server admission plugins.
        admissionControl:
            - name: PodSecurity # Name is the name of the admission controller.
              # Configuration is an embedded configuration object to be used as the plugin's
              configuration:
                apiVersion: pod-security.admission.config.k8s.io/v1alpha1
                defaults:
                    audit: restricted
                    audit-version: latest
                    enforce: baseline
                    enforce-version: latest
                    warn: restricted
                    warn-version: latest
                exemptions:
                    namespaces:
                        - kube-system
                    runtimeClasses: []
                    usernames: []
                kind: PodSecurityConfiguration
                ...

SeccompDefault

一般的にデフォルトの状態ではKubernetesクラスタにデプロイするPodにはseccompによるsystemcallの制限は適用されませんが、SeccompDefaultを有効化することでコンテナランタイム(containerdなどのCRIランタイム)で定義されているseccomp profileが自動的にPodに適用され、Pod内のコンテナから実行できるsystemcallが制限されます。
Talos Linuxのデフォルトのmachine configでは、次のようにkubeletの設定としてdefaultRuntimeSeccompProfileEnabled: trueという設定が行われており、SeccompDefaultが有効になっています。

controlplane.yaml/worker.yaml

    # Used to provide additional options to the kubelet.
    kubelet:
        ...
        defaultRuntimeSeccompProfileEnabled: true # Enable container runtime default Seccomp profile.
        ...

※KubernetesにおけるSeccompの使用については過去の登壇で使用した資料がありますのであわせてご覧ください。

machine configの変更

今回はデフォルトの状態から、以下の設定変更を行いました。

/etc/hostsの設定

今回は検証環境ということもあるため、各サーバーが名前解決を行うことができるよう/etc/hostsに各サーバーのホスト名とIPアドレスを設定します。
controlplane.yamlworker.yamlそれぞれに対し、以下の内容を追加します。

controlplane.yaml/worker.yaml

# network: {}
network:
    ...
    # # Allows for extra entries to be added to the `/etc/hosts` file
        extraHostEntries:
        - ip: 192.168.2.140
          aliases:
          - k8s-talos-cp01
        - ip: 192.168.2.141
          aliases:
          - k8s-talos-node01
        - ip: 192.168.2.142
          aliases:
          - k8s-talos-node02
     ...

CNI Pluginの変更

Talos LinuxでKubernetesクラスタを構築する場合、デフォルトではCNI Pluginとしてflannelが使用されるようです。
筆者は普段calicoを使用することが多いので、Kubernetesクラスタ構築後に別途インストールできるよう、CNI Pluginの自動インストールを無効化しておきます。
controlplane.yamlworker.yamlそれぞれに対し、以下の変更を行います。
また、Kubernetes内のPodやServiceが使用するネットワークレンジもここで指定できます。

controlplane.yaml/worker.yaml

# Provides cluster specific configuration options.
cluster:
    ...
    network:
        dnsDomain: cluster.local # The domain used by Kubernetes DNS.
        # The pod subnet CIDR.
        podSubnets:
            - 10.244.0.0/16
        # The service subnet CIDR.
        serviceSubnets:
            - 10.96.0.0/12
        
        # # The CNI used.
        cni: 
          name: none

なお、公式ドキュメントでは同じくCNI PluginであるCiliumをインストールする方法について記載があるため、必要に応じて参照してください。

https://www.talos.dev/v1.7/kubernetes-guides/network/deploying-cilium/

PodSecurity Admissionの無効化

今回はこの後の検証の都合上、PodSecurity Admissionのデフォルト設定(AdmissionConfigurationとして定義されるKubernetesクラスタ全体に適用される設定)を無効化します。
controlplane.yamlにて、該当箇所をコメントアウトします。

controlplane.yaml

    # API server specific configuration options.
    apiServer:
        ...
        # Configure the API server admission plugins.
        # admissionControl:
        #     - name: PodSecurity # Name is the name of the admission controller.
        #       # Configuration is an embedded configuration object to be used as the plugin's
        #       configuration:
        #         apiVersion: pod-security.admission.config.k8s.io/v1alpha1
        #         defaults:
        #             audit: restricted
        #             audit-version: latest
        #             enforce: baseline
        #             enforce-version: latest
        #             warn: restricted
        #             warn-version: latest
        #         exemptions:
        #             namespaces:
        #                 - kube-system
        #             runtimeClasses: []
        #             usernames: []
        #         kind: PodSecurityConfiguration

(参考)machine configの全体像

参考までに、以下が今回筆者が使用したmachine configになります。
※IPアドレスや証明書情報などもそのまま記載しているのでご注意ください。

controlplane.yaml
version: v1alpha1 # Indicates the schema used to decode the contents.
debug: false # Enable verbose logging to the console.
persist: true
# Provides machine specific configuration options.
machine:
    type: controlplane # Defines the role of the machine within the cluster.
    token: toxf8p.zgsxaxqv9u1qnavn # The `token` is used by a machine to join the PKI of the cluster.
    # The root certificate authority of the PKI.
    ca:
        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQekNCOHFBREFnRUNBaEVBLzVvL0R6M1poOHNtRERMNWZKUjZSekFGQmdNclpYQXdFREVPTUF3R0ExVUUKQ2hNRmRHRnNiM013SGhjTk1qUXdOakkyTVRjeE5qQXpXaGNOTXpRd05qSTBNVGN4TmpBeldqQVFNUTR3REFZRApWUVFLRXdWMFlXeHZjekFxTUFVR0F5dGxjQU1oQUNPRlhYdmM0NFdqZGh5R05oeWkwOXZVOXZZYTNqRU5GLzlXCm1CcUxIQVR6bzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUcKQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkNmaFhsQmh3TzVnVEI0NQphbE9TTXhTaGxjeGVNQVVHQXl0bGNBTkJBS2tVZ0tqN1RTNmMzNmtXZ0JRMHVnRlB3djZ3N3F0RXJSR25OQjBsCjNTTWNCdnQ0VmFFSlIvSHpEblRFK2JjVmtBd0Z5WG5mNlJXV2tsb1pXMElweWdRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        key: LS0tLS1CRUdJTiBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0KTUM0Q0FRQXdCUVlESzJWd0JDSUVJQzRqOTFFS0JGcXRvTEw5MitNOEpSOWkyRzdiK0dzekYvSDF0SDlzcEU4UgotLS0tLUVORCBFRDI1NTE5IFBSSVZBVEUgS0VZLS0tLS0K
    # Extra certificate subject alternative names for the machine's certificate.
    certSANs: []
    #   # Uncomment this to enable SANs.
    #   - 10.0.0.10
    #   - 172.16.0.10
    #   - 192.168.0.10

    # Used to provide additional options to the kubelet.
    kubelet:
        image: ghcr.io/siderolabs/kubelet:v1.30.1 # The `image` field is an optional reference to an alternative kubelet image.
        defaultRuntimeSeccompProfileEnabled: true # Enable container runtime default Seccomp profile.
        disableManifestsDirectory: true # The `disableManifestsDirectory` field configures the kubelet to get static pod manifests from the /etc/kubernetes/manifests directory.
        
        # # The `ClusterDNS` field is an optional reference to an alternative kubelet clusterDNS ip list.
        # clusterDNS:
        #     - 10.96.0.10
        #     - 169.254.2.53

        # # The `extraArgs` field is used to provide additional flags to the kubelet.
        # extraArgs:
        #     key: value

        # # The `extraMounts` field is used to add additional mounts to the kubelet container.
        # extraMounts:
        #     - destination: /var/lib/example # Destination is the absolute path where the mount will be placed in the container.
        #       type: bind # Type specifies the mount kind.
        #       source: /var/lib/example # Source specifies the source path of the mount.
        #       # Options are fstab style mount options.
        #       options:
        #         - bind
        #         - rshared
        #         - rw

        # # The `extraConfig` field is used to provide kubelet configuration overrides.
        # extraConfig:
        #     serverTLSBootstrap: true

        # # The `KubeletCredentialProviderConfig` field is used to provide kubelet credential configuration.
        # credentialProviderConfig:
        #     apiVersion: kubelet.config.k8s.io/v1
        #     kind: CredentialProviderConfig
        #     providers:
        #         - apiVersion: credentialprovider.kubelet.k8s.io/v1
        #           defaultCacheDuration: 12h
        #           matchImages:
        #             - '*.dkr.ecr.*.amazonaws.com'
        #             - '*.dkr.ecr.*.amazonaws.com.cn'
        #             - '*.dkr.ecr-fips.*.amazonaws.com'
        #             - '*.dkr.ecr.us-iso-east-1.c2s.ic.gov'
        #             - '*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov'
        #           name: ecr-credential-provider

        # # The `nodeIP` field is used to configure `--node-ip` flag for the kubelet.
        # nodeIP:
        #     # The `validSubnets` field configures the networks to pick kubelet node IP from.
        #     validSubnets:
        #         - 10.0.0.0/8
        #         - '!10.0.0.3/32'
        #         - fdc7::/16
    # Provides machine specific network configuration options.
    network: 
    # # `interfaces` is used to define the network interface configuration.
    # interfaces:
    #     - interface: enp0s1 # The interface name.
    #       # Assigns static IP addresses to the interface.
    #       addresses:
    #         - 192.168.2.0/24
    #       # A list of routes associated with the interface.
    #       routes:
    #         - network: 0.0.0.0/0 # The route's network (destination).
    #           gateway: 192.168.2.1 # The route's gateway (if empty, creates link scope route).
    #           metric: 1024 # The optional metric for the route.
    #       mtu: 1500 # The interface's MTU.
    #       
    #       # # Picks a network device using the selector.

    #       # # select a device with bus prefix 00:*.
    #       # deviceSelector:
    #       #     busPath: 00:* # PCI, USB bus prefix, supports matching by wildcard.
    #       # # select a device with mac address matching `*:f0:ab` and `virtio` kernel driver.
    #       # deviceSelector:
    #       #     hardwareAddr: '*:f0:ab' # Device hardware address, supports matching by wildcard.
    #       #     driver: virtio # Kernel driver, supports matching by wildcard.
    #       # # select a device with bus prefix 00:*, a device with mac address matching `*:f0:ab` and `virtio` kernel driver.
    #       # deviceSelector:
    #       #     - busPath: 00:* # PCI, USB bus prefix, supports matching by wildcard.
    #       #     - hardwareAddr: '*:f0:ab' # Device hardware address, supports matching by wildcard.
    #       #       driver: virtio # Kernel driver, supports matching by wildcard.

    #       # # Bond specific options.
    #       # bond:
    #       #     # The interfaces that make up the bond.
    #       #     interfaces:
    #       #         - enp2s0
    #       #         - enp2s1
    #       #     # Picks a network device using the selector.
    #       #     deviceSelectors:
    #       #         - busPath: 00:* # PCI, USB bus prefix, supports matching by wildcard.
    #       #         - hardwareAddr: '*:f0:ab' # Device hardware address, supports matching by wildcard.
    #       #           driver: virtio # Kernel driver, supports matching by wildcard.
    #       #     mode: 802.3ad # A bond option.
    #       #     lacpRate: fast # A bond option.

    #       # # Bridge specific options.
    #       # bridge:
    #       #     # The interfaces that make up the bridge.
    #       #     interfaces:
    #       #         - enxda4042ca9a51
    #       #         - enxae2a6774c259
    #       #     # A bridge option.
    #       #     stp:
    #       #         enabled: true # Whether Spanning Tree Protocol (STP) is enabled.

    #       # # Indicates if DHCP should be used to configure the interface.
    #       # dhcp: true

    #       # # DHCP specific options.
    #       # dhcpOptions:
    #       #     routeMetric: 1024 # The priority of all routes received via DHCP.

    #       # # Wireguard specific configuration.

    #       # # wireguard server example
    #       # wireguard:
    #       #     privateKey: ABCDEF... # Specifies a private key configuration (base64 encoded).
    #       #     listenPort: 51111 # Specifies a device's listening port.
    #       #     # Specifies a list of peer configurations to apply to a device.
    #       #     peers:
    #       #         - publicKey: ABCDEF... # Specifies the public key of this peer.
    #       #           endpoint: 192.168.1.3 # Specifies the endpoint of this peer entry.
    #       #           # AllowedIPs specifies a list of allowed IP addresses in CIDR notation for this peer.
    #       #           allowedIPs:
    #       #             - 192.168.1.0/24
    #       # # wireguard peer example
    #       # wireguard:
    #       #     privateKey: ABCDEF... # Specifies a private key configuration (base64 encoded).
    #       #     # Specifies a list of peer configurations to apply to a device.
    #       #     peers:
    #       #         - publicKey: ABCDEF... # Specifies the public key of this peer.
    #       #           endpoint: 192.168.1.2:51822 # Specifies the endpoint of this peer entry.
    #       #           persistentKeepaliveInterval: 10s # Specifies the persistent keepalive interval for this peer.
    #       #           # AllowedIPs specifies a list of allowed IP addresses in CIDR notation for this peer.
    #       #           allowedIPs:
    #       #             - 192.168.1.0/24

    #       # # Virtual (shared) IP address configuration.

    #       # # layer2 vip example
    #       # vip:
    #       #     ip: 172.16.199.55 # Specifies the IP address to be used.

    # # Used to statically set the nameservers for the machine.
    # nameservers:
    #     - 8.8.8.8
    #     - 1.1.1.1

    # # Allows for extra entries to be added to the `/etc/hosts` file
        extraHostEntries:
        - ip: 192.168.2.140
          aliases:
          - k8s-talos-cp01
        - ip: 192.168.2.141
          aliases:
          - k8s-talos-node01
        - ip: 192.168.2.142
          aliases:
          - k8s-talos-node02

    # # Configures KubeSpan feature.
    # kubespan:
    #     enabled: true # Enable the KubeSpan feature.

    # Used to provide instructions for installations.
    install:
        disk: /dev/sda # The disk used for installations.
        image: ghcr.io/siderolabs/installer:v1.7.5 # Allows for supplying the image used to perform the installation.
        wipe: false # Indicates if the installation disk should be wiped at installation time.
        
        # # Look up disk using disk attributes like model, size, serial and others.
        # diskSelector:
        #     size: 4GB # Disk size.
        #     model: WDC* # Disk model `/sys/block/<dev>/device/model`.
        #     busPath: /pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0 # Disk bus path.

        # # Allows for supplying extra kernel args via the bootloader.
        # extraKernelArgs:
        #     - talos.platform=metal
        #     - reboot=k

        # # Allows for supplying additional system extension images to install on top of base Talos image.
        # extensions:
        #     - image: ghcr.io/siderolabs/gvisor:20220117.0-v1.0.0 # System extension image.
    # Used to configure the machine's container image registry mirrors.
    registries: {}
    # # Specifies mirror configuration for each registry host namespace.
    # mirrors:
    #     ghcr.io:
    #         # List of endpoints (URLs) for registry mirrors to use.
    #         endpoints:
    #             - https://registry.insecure
    #             - https://ghcr.io/v2/

    # # Specifies TLS & auth configuration for HTTPS image registries.
    # config:
    #     registry.insecure:
    #         # The TLS configuration for the registry.
    #         tls:
    #             insecureSkipVerify: true # Skip TLS server certificate verification (not recommended).
    #             
    #             # # Enable mutual TLS authentication with the registry.
    #             # clientIdentity:
    #             #     crt: LS0tIEVYQU1QTEUgQ0VSVElGSUNBVEUgLS0t
    #             #     key: LS0tIEVYQU1QTEUgS0VZIC0tLQ==
    #         
    #         # # The auth configuration for this registry.
    #         # auth:
    #         #     username: username # Optional registry authentication.
    #         #     password: password # Optional registry authentication.

    # Features describe individual Talos features that can be switched on or off.
    features:
        rbac: true # Enable role-based access control (RBAC).
        stableHostname: true # Enable stable default hostname.
        apidCheckExtKeyUsage: true # Enable checks for extended key usage of client certificates in apid.
        diskQuotaSupport: true # Enable XFS project quota support for EPHEMERAL partition and user disks.
        # KubePrism - local proxy/load balancer on defined port that will distribute
        kubePrism:
            enabled: true # Enable KubePrism support - will start local load balancing proxy.
            port: 7445 # KubePrism port.
        # Configures host DNS caching resolver.
        hostDNS:
            enabled: true # Enable host DNS caching resolver.
        
        # # Configure Talos API access from Kubernetes pods.
        # kubernetesTalosAPIAccess:
        #     enabled: true # Enable Talos API access from Kubernetes pods.
        #     # The list of Talos API roles which can be granted for access from Kubernetes pods.
        #     allowedRoles:
        #         - os:reader
        #     # The list of Kubernetes namespaces Talos API access is available from.
        #     allowedKubernetesNamespaces:
        #         - kube-system
    
    # # Provides machine specific control plane configuration options.

    # # ControlPlane definition example.
    # controlPlane:
    #     # Controller manager machine specific configuration options.
    #     controllerManager:
    #         disabled: false # Disable kube-controller-manager on the node.
    #     # Scheduler machine specific configuration options.
    #     scheduler:
    #         disabled: true # Disable kube-scheduler on the node.

    # # Used to provide static pod definitions to be run by the kubelet directly bypassing the kube-apiserver.

    # # nginx static pod.
    # pods:
    #     - apiVersion: v1
    #       kind: pod
    #       metadata:
    #         name: nginx
    #       spec:
    #         containers:
    #             - image: nginx
    #               name: nginx

    # # Used to partition, format and mount additional disks.

    # # MachineDisks list example.
    # disks:
    #     - device: /dev/sdb # The name of the disk to use.
    #       # A list of partitions to create on the disk.
    #       partitions:
    #         - mountpoint: /var/mnt/extra # Where to mount the partition.
    #           
    #           # # The size of partition: either bytes or human readable representation. If `size:` is omitted, the partition is sized to occupy the full disk.

    #           # # Human readable representation.
    #           # size: 100 MB
    #           # # Precise value in bytes.
    #           # size: 1073741824

    # # Allows the addition of user specified files.

    # # MachineFiles usage example.
    # files:
    #     - content: '...' # The contents of the file.
    #       permissions: 0o666 # The file's permissions in octal.
    #       path: /tmp/file.txt # The path of the file.
    #       op: append # The operation to use

    # # The `env` field allows for the addition of environment variables.

    # # Environment variables definition examples.
    # env:
    #     GRPC_GO_LOG_SEVERITY_LEVEL: info
    #     GRPC_GO_LOG_VERBOSITY_LEVEL: "99"
    #     https_proxy: http://SERVER:PORT/
    # env:
    #     GRPC_GO_LOG_SEVERITY_LEVEL: error
    #     https_proxy: https://USERNAME:PASSWORD@SERVER:PORT/
    # env:
    #     https_proxy: http://DOMAIN\USERNAME:PASSWORD@SERVER:PORT/

    # # Used to configure the machine's time settings.

    # # Example configuration for cloudflare ntp server.
    # time:
    #     disabled: false # Indicates if the time service is disabled for the machine.
    #     # description: |
    #     servers:
    #         - time.cloudflare.com
    #     bootTimeout: 2m0s # Specifies the timeout when the node time is considered to be in sync unlocking the boot sequence.

    # # Used to configure the machine's sysctls.

    # # MachineSysctls usage example.
    # sysctls:
    #     kernel.domainname: talos.dev
    #     net.ipv4.ip_forward: "0"
    #     net/ipv6/conf/eth0.100/disable_ipv6: "1"

    # # Used to configure the machine's sysfs.

    # # MachineSysfs usage example.
    # sysfs:
    #     devices.system.cpu.cpu0.cpufreq.scaling_governor: performance

    # # Machine system disk encryption configuration.
    # systemDiskEncryption:
    #     # Ephemeral partition encryption.
    #     ephemeral:
    #         provider: luks2 # Encryption provider to use for the encryption.
    #         # Defines the encryption keys generation and storage method.
    #         keys:
    #             - # Deterministically generated key from the node UUID and PartitionLabel.
    #               nodeID: {}
    #               slot: 0 # Key slot number for LUKS2 encryption.
    #               
    #               # # KMS managed encryption key.
    #               # kms:
    #               #     endpoint: https://192.168.88.21:4443 # KMS endpoint to Seal/Unseal the key.
    #         
    #         # # Cipher kind to use for the encryption. Depends on the encryption provider.
    #         # cipher: aes-xts-plain64

    #         # # Defines the encryption sector size.
    #         # blockSize: 4096

    #         # # Additional --perf parameters for the LUKS2 encryption.
    #         # options:
    #         #     - no_read_workqueue
    #         #     - no_write_workqueue

    # # Configures the udev system.
    # udev:
    #     # List of udev rules to apply to the udev system
    #     rules:
    #         - SUBSYSTEM=="drm", KERNEL=="renderD*", GROUP="44", MODE="0660"

    # # Configures the logging system.
    # logging:
    #     # Logging destination.
    #     destinations:
    #         - endpoint: tcp://1.2.3.4:12345 # Where to send logs. Supported protocols are "tcp" and "udp".
    #           format: json_lines # Logs format.

    # # Configures the kernel.
    # kernel:
    #     # Kernel modules to load.
    #     modules:
    #         - name: brtfs # Module name.

    # # Configures the seccomp profiles for the machine.
    # seccompProfiles:
    #     - name: audit.json # The `name` field is used to provide the file name of the seccomp profile.
    #       # The `value` field is used to provide the seccomp profile.
    #       value:
    #         defaultAction: SCMP_ACT_LOG

    # # Configures the node labels for the machine.

    # # node labels example.
    # nodeLabels:
    #     exampleLabel: exampleLabelValue

    # # Configures the node taints for the machine. Effect is optional.

    # # node taints example.
    # nodeTaints:
    #     exampleTaint: exampleTaintValue:NoSchedule
# Provides cluster specific configuration options.
cluster:
    id: BWUQjnVv7QnZOkH-L1x41CIWXqtEo2PFcJeqooSwfnI= # Globally unique identifier for this cluster (base64 encoded random 32 bytes).
    secret: 8fLzwGc0HJbFSCZazQr8NRQToVFosXu2M8n0eFgiZF4= # Shared secret of cluster (base64 encoded random 32 bytes).
    # Provides control plane specific configuration options.
    controlPlane:
        endpoint: https://k8s-talos-cp01:6443 # Endpoint is the canonical controlplane endpoint, which can be an IP address or a DNS hostname.
    clusterName: k8s-talos-cluster # Configures the cluster's name.
    # Provides cluster specific network configuration options.
    network:
        dnsDomain: cluster.local # The domain used by Kubernetes DNS.
        # The pod subnet CIDR.
        podSubnets:
            - 10.244.0.0/16
        # The service subnet CIDR.
        serviceSubnets:
            - 10.96.0.0/12
        
        # # The CNI used.
        cni: 
          name: none
        #     # URLs containing manifests to apply for the CNI.
        #     urls:
        #         - https://docs.projectcalico.org/archive/v3.20/manifests/canal.yaml
    token: u7iftl.y6gon6nukk202arm # The [bootstrap token](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/) used to join the cluster.
    secretboxEncryptionSecret: YBhPhXLDWxemXgxgMPTGwGpuHSc4kg8bkSTTU5gUazU= # A key used for the [encryption of secret data at rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/).
    # The base64 encoded root certificate authority used by Kubernetes.
    ca:
        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpVENDQVRDZ0F3SUJBZ0lSQU5yQ0Ywa2RtQ2ZIRXBVY2RCOXlYNjB3Q2dZSUtvWkl6ajBFQXdJd0ZURVQKTUJFR0ExVUVDaE1LYTNWaVpYSnVaWFJsY3pBZUZ3MHlOREEyTWpZeE56RTJNRE5hRncwek5EQTJNalF4TnpFMgpNRE5hTUJVeEV6QVJCZ05WQkFvVENtdDFZbVZ5Ym1WMFpYTXdXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CCkJ3TkNBQVIzVU9GN09NRjEvbDQ4UmdFRjQxVDgrZWJCYzB6K0doUTRSd2dpK0RMRHhkVVo1OUFoZUNlQTl6alYKUURma084Zk1YTnQ1RXkwM0tTMVNNdUlhWm80S28yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXdIUVlEVlIwbApCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPCkJCWUVGQWVKYW5ic0IvdmErU2xpM0luelpzUkx2TjhwTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUJxMEJUVVgKVWo1QjRNUEhVNUsxUTZ0SUVoQlVXWjZTM3lYTFBKYUttWXZLQWlCd2J6SzRCV1hOVXNWNlV3dWVuZEQrQ2MxSAp6cDJkK090aFlXRVIxRDVuZ1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUZ4alhpci96TFI4SDVDMUpDdkMvcVJuQzk1MDIrVlRRdm01VXZZS2diVWFvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFZDFEaGV6akJkZjVlUEVZQkJlTlUvUG5td1hOTS9ob1VPRWNJSXZneXc4WFZHZWZRSVhnbgpnUGM0MVVBMzVEdkh6RnpiZVJNdE55a3RVakxpR21hT0NnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
    # The base64 encoded aggregator certificate authority used by Kubernetes for front-proxy certificate generation.
    aggregatorCA:
        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJYekNDQVFXZ0F3SUJBZ0lRYUdTOVdwQUN6RXJObzArMkVqdnJuREFLQmdncWhrak9QUVFEQWpBQU1CNFgKRFRJME1EWXlOakUzTVRZd00xb1hEVE0wTURZeU5ERTNNVFl3TTFvd0FEQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxRwpTTTQ5QXdFSEEwSUFCT05veHRSdUNMcmkwTTRoenVLVXF5Nm9ROGdxZ2ozNFJWdVdYcHNCWEtFakk4TVFyMWlXCnJtUnJpZjVvK3BzMXpZSTBJYitVTGdBNElGc3Z3ajFXNzY2allUQmZNQTRHQTFVZER3RUIvd1FFQXdJQ2hEQWQKQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSUt3WUJCUVVIQXdJd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZApCZ05WSFE0RUZnUVUvMWZXYXVudnVnNU9nOTl6TlRJOG5yUElwM0F3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUlnClNPcEQ3STVEbXo5SHhRYWhJVTZvbjNuYm9ZZHU1V1V5VWlnSlhiV044amdDSVFEeUk4SndmeXA3cEJaU0Y4MVEKQTVUbDhxOE9oSU02UzRzdUJtUlpJMUNZclE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUFlSnFOR2ZiSExyZHVUTkFrK0VKN2pTQ0hpWHBTa1gybWJCTDF1b3JLdG9vQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFNDJqRzFHNEl1dUxRemlITzRwU3JMcWhEeUNxQ1BmaEZXNVplbXdGY29TTWp3eEN2V0phdQpaR3VKL21qNm16WE5nalFodjVRdUFEZ2dXeS9DUFZidnJnPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
    # The base64 encoded private key for service account token generation.
    serviceAccount:
        key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBMHYvR0hRbktRcTBGR3B5aEdrY3BHeHNIZ3pJY2tqMlJBdGUrVU4vSW9hYXJYbHdtCncxTmc4eStwQ0xMTkZkOHg5bk0zTFpmcW8wNFFXSGFCcWRob1RWK3JPa3pnUWtxREhZaHdOdnJsK3ZkZkN5N08KU3N4c2dwbzVSM0tlMW9XckpIYmRLcXllYURMbzVCVFBsNEt5Uk5CL0NBSk1IenZEMjh2NitqRnROd2FwREJzbwpqZjFTOUtweENLSmtVTVFNdGhFVWFpRHZ5WXhUUkxkUCttU2lsOVhibmpJeGJSempHTU1YZFNROUIxaXJuSCtlCk5hN1laM1ZZKytqdlo5dExHY0tqN2JGTkptNWtHWmdsQ0pML3RaN1FvUndheFJuK0dJYU1hVFZZK1AxQ0VKeDUKWU1RVTA4WXJhSnZScGtsenBTejlaVnB0WlNmdmtKeTk0b21HRkk5dWJUclRGeHZXV2Jwd0Y3YnpRaUNobWlVOAprRkNyaE5obTVlc2tuSzhDNHdUVnBPNmN5RmNON3ZjM0FCTEdKdE5kZ2I2WUJLTXpYc0ZzbFpLbjk0UmdsQkhUCllkV1c3N0tONHpNYlYvV285QWtCNnRJcmc4d2VVckMvWVNLNG9SaTl2NkVDRWxMc0VyRHo4L2F0VDVpZHNQQmIKeGRhNUI3bTB3VWl1cjhZeEozOXN3V3pqZkMwRHFNelA5TmhrSCs3K3RYVFlSVkowTFpabm1xNnMwbmlaRVg0bwplVHFLWmNxcXJrNGpsR3lCN05iOHp1U2o5M2ZCMi9QRWdKMDcySDRhYlFDMTJKRU1EeEhnVTNuZ0dFWkd1WTNuCjhuL2FJbnF6TXpYeG14L25RbUg5eVFrSnpLQ2xtZDJJL3BMeklOYnBiNTk5emhxQTltYzA2TVBNd0JzQ0F3RUEKQVFLQ0FnRUFwa3JsRmMrNGM3SXZHcGtsTXpPd1J1ZVhsU095ZHVORTNXdXhWOFgzTnNmSHVkZUF5V0oyUDFOcApzaXhSREJMYktyUUZZYzZnSTFLTCtWeDB0cXFURVovN3NEZ1Vhc3FVNlhxMWplOVJ2K2lrSklrZ0ZyMWtLODVtCnBGUEdzYVdwaTFTTzNHb3Rja3ZsVnBTOFExbkRMQTd5Znhwb2FobE5OSFpmK0QxcUtQcjcwa201UGFiUWNYbS8KR2lINlU5a2ZkNEtnaDBBc0c3bVhpc202bzhvYWh2WUtYM1NKbGNnMWh6ZUN6bFRnTUdFRzU1R0EzQ2hQNzhJQgpmcEJIMXA5ellmc1AvVzVHTXFyQUE1ZndZQUNTdmM1TCtSM1FUMVU3K0pKYUtUVGRTV2M0WVNVaFdFMVJhTkovCk5iUFFtSEM5VHduVkw4TUVBcnhseDZCdzJ4Q3Q5U2lGeW9VRTBVR0dTUXdHeVpqZTh6V1dZYUtEbXNKVFowRDkKY2pHWWU5RjJ4Qmh3YTFNbzQ0L25kVHUxVE9nVVQzNzFIeStOZVFDN1lTTkVjeU9VMi9PT085dW9SOUxNQW1KegplQjlXUS9qemNjdTQ2YTVJQ3lFbldjbDcvdDQyeTd6S0Rmb0VyRGNqckYrVm5RaVo2YTl5Vm1kdTlDdjBiY0FHCmhyeXZtaUIwL2c2MldONnczQUdqTmZld0lsYjNIRFEzcmJ6ZVVYaU1jejFjZVV6QUlJY2tjN0kwQk5OU2l6Q2QKS2FjTUJORGVacG1jdFhsRTh0N3VORHlMYjFpZFAwcTU2RHNDWnpncEhOcklhQ3V6YzJDU1pkTkV3U3RsNUZSTQoxdUJyNWN1ZlFFWTVERnRnV3crZ3Nwdmk0WGUwNjVNdy9QZ0Y0NlZXVDlYOEszYWNuTGtDZ2dFQkFOU2RncWorCjJTTnVMME0zKzRBM0I3aW5Dd3FOb1hYa2hvODVaZlU2K2luc3BBSk1KMkIveEQrVjNlOGpQSW96T0ZPZFNEbFEKQjhrZE11Q1o1ajNOU2hsWlkyUk9HNnJZL2hFTFY0TmUweHpmK014WGlQeEV2T0dTWWdpUXBQbWRXYWlFMUFpVwp4aXBaK0VsTEdLRzdTS0RUVVZGTlZQTEpGRVIzcFZNUlpkVWRvTEt0SDZPVjEwdmRtQ3dtcC83NUZpWW0zUkV0Cit1QklySzZYZUdKUDA5d25adktRU0x0N25xVnJlOE5kcStPdWFDTWNMWFM4M0pibTJ5ejFlV2tTWDRXSWhxWkEKY0Z6ekNha3pIdm00SXVvWVpmN1JtOGNweUZVR2pWaENSVFdWMStyQy91Y0NDNlAxUXovNExkdXpvbGVUT0ExVAp0K0ROM1dTT0VxZUFMdGNDZ2dFQkFQNE4xdVRYVnFMb1Jrbi9rempqZU5rMEZNbUZwVFZyQjh6UjFOWjJGeTY0ClFabmZGN1JUWDZHaHczZ01XSmYxRll4NGdydDhSandHNkJFNmliNE91ZTBESG5MdEVVSDBEbXBBbmxhUW44RHoKOHYwaHREK212bmJ6MUlwYk96WGNZMll1akQ2emdCVUE3ZXBmamVycmJJZ1FocnptMTMzM3J6SnRCTFZMVmk3Kwp5V1BFSzBvNVdyTk9jUGJwUEtMNGNScFNMdEMyMzQ3a2I0UEFPSWxLR1lDODkvd2hNQUpIcmR1Q2RxMEY1VGdnClFwSHpKR0krOWQxdmEzdWdxWCs1TTdPRzc4VlVQamN0enRYTFNsRmhTSGtOZ2l6TGtMSHNWSWFWdlNPL3RkVXkKNW5PRUNCSDZaamkrK210d2xSdWh3SkNjbndFNkVCQkR5WTNFS25CV3BGMENnZ0VBRG14NUZybmpSVElPWnNMLwpmdDA4MnR3S05iY1NBd3R6elhlWllSK1ZKUTcydVdrdEtyREFRWWdMUEZQcG9YNkVEYmdYMUR1SHE2OGRhbnRHClVWOEI3ZUpRaWRkNnJRWjNoZlI5QlY2RGQrd0IxdXNCVWd2ZnZIWFB6TUR6VURQS2gxSXJpRUdpUS9GQ2xNWlIKYjNkakgvWDJDRXYwdlZ2QzBqcERydlQ1TVpJRyt0Z2YwMXN3OWVhY2tqSTFKMmtDaGFnUlN6OFJTL0hpTlIzMQpmc1hubTRIWXpBL1p2MDVObnU5QndDazBwZ2VJN1FqV1ZKc1RZL0ZaWVIxdUZTQzM5amtpMlZoNXh2Ujk3VXFZCmlWeGlrZnNCd0YyNzhiRDE5RDZ6akE5QzNyWEJwaDJBYVcrTUZwMW02SW9Qb2wzM1gzV1BVZWdpQzFBcitzeGcKbTVob2xRS0NBUUFsZjFOdGVWOGZNbHRWaHJSckhCLzFKeHUrVnN4NG92Q0d5WjI1ZmJxVU9idnRBeUdUaXc2OQpZNHZmUnlzNFdvTXd0WVRPT1Z5QWRhQ0JFbnZNSW81TXJqNHJSbFJhd0xQeitNK21CVGlmR1NLUFBBOUhxY3ZJCjhObzVCWmdxcmZtNTFqcjY4akdBYUIrMWpSNzhRbjFGWS9NUEpKOC94M1FEWkZYaWtGa0xISzRLM0tSckV5WVEKK3czdlU2T1Foa3pqVHFmOFJGR2czSlNkQkowVG5tMC9OQ1VDQUwvK1JpZ2lFeEtESFRDazVSWU9ScTNqRmxuaApzaFZTTFBkM2s1Vk85U2Frb0hlQ1cyK0EzTDErWDNaNzc0TjhLeHVUTjBlT2ljRmQ2bWpqSzkwWnhhNFBRVDhmCk53anRITFBWWFQxMzJyWVpUMEdadFBlbHhnTmhpMWc5QW9JQkFGa0krOFBtRXI2blFWbmFlY2FDUENHeURPSnEKeisyNFEvRGdNcGRZVEhWS2h0cTUrS3NKS3V1RXIvdjRraWpvRG93cW5aVXNlc21OS2ZPS3BSNytWY25wSDhWVQpZYVE5TjJrNkE2bU9NRCtyK0kvTU44U3UveW10a2M4WUU0djNRNHNEZGdqK2hwa244QjBJUnZONzA4YjNyeGZPCmExNG1rNUNOTlNoOTZPTkJpcU13RHJOeEF5aUtYWnFob1lJeTlsNjR6ZlpHRXBNcTlpU1lpalp4REVJQnd1aEUKcW9xcURWZEQ3VFJQUDhYSXRPb21JZXFZMSt0RHlvbXpvbUtmTTU3ckROVVlDVmYxZmhncmxtc2J3Wm9ycDlLTApkTHVkeHllMzlqb0hSbFlEbUYrc0R6V0VaRzlXWEExN0NyeFdISm9OeTNVeEh3S1lrMHp0OTQ3em8vOD0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K
    # API server specific configuration options.
    apiServer:
        image: registry.k8s.io/kube-apiserver:v1.30.1 # The container image used in the API server manifest.
        # Extra certificate subject alternative names for the API server's certificate.
        certSANs:
            - k8s-talos-cp01
        disablePodSecurityPolicy: true # Disable PodSecurityPolicy in the API server and default manifests.
        # Configure the API server admission plugins.
        # admissionControl:
        #     - name: PodSecurity # Name is the name of the admission controller.
        #       # Configuration is an embedded configuration object to be used as the plugin's
        #       configuration:
        #         apiVersion: pod-security.admission.config.k8s.io/v1alpha1
        #         defaults:
        #             audit: restricted
        #             audit-version: latest
        #             enforce: baseline
        #             enforce-version: latest
        #             warn: restricted
        #             warn-version: latest
        #         exemptions:
        #             namespaces:
        #                 - kube-system
        #             runtimeClasses: []
        #             usernames: []
        #         kind: PodSecurityConfiguration
        # Configure the API server audit policy.
        auditPolicy:
            apiVersion: audit.k8s.io/v1
            kind: Policy
            rules:
                - level: Metadata
    # Controller manager server specific configuration options.
    controllerManager:
        image: registry.k8s.io/kube-controller-manager:v1.30.1 # The container image used in the controller manager manifest.
    # Kube-proxy server-specific configuration options
    proxy:
        image: registry.k8s.io/kube-proxy:v1.30.1 # The container image used in the kube-proxy manifest.
        
        # # Disable kube-proxy deployment on cluster bootstrap.
        # disabled: false
    # Scheduler server specific configuration options.
    scheduler:
        image: registry.k8s.io/kube-scheduler:v1.30.1 # The container image used in the scheduler manifest.
    # Configures cluster member discovery.
    discovery:
        enabled: true # Enable the cluster membership discovery feature.
        # Configure registries used for cluster member discovery.
        registries:
            # Kubernetes registry uses Kubernetes API server to discover cluster members and stores additional information
            kubernetes:
                disabled: true # Disable Kubernetes discovery registry.
            # Service registry is using an external service to push and pull information about cluster members.
            service: {}
            # # External service endpoint.
            # endpoint: https://discovery.talos.dev/
    # Etcd specific configuration options.
    etcd:
        # The `ca` is the root certificate authority of the PKI.
        ca:
            crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJmekNDQVNTZ0F3SUJBZ0lSQUxCMUtuelUvekdIelFtTEpxaUFaR3N3Q2dZSUtvWkl6ajBFQXdJd0R6RU4KTUFzR0ExVUVDaE1FWlhSalpEQWVGdzB5TkRBMk1qWXhOekUyTUROYUZ3MHpOREEyTWpReE56RTJNRE5hTUE4eApEVEFMQmdOVkJBb1RCR1YwWTJRd1dUQVRCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFUQU52N1lIWkZEClN1SFZTL2ExTlJNQXpqa0k0QmxmSnBFYm1sR3BSRVhhQVR3YUZRbUVLeHR0WDhLZ3grTVdqQVNkSXFmcDVidksKZXMzVzMvTG44dUVNbzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSApBd0VHQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkoxandtRUVhR0Y4CmwwTnl2ZWluUDJIeUdZNkJNQW9HQ0NxR1NNNDlCQU1DQTBrQU1FWUNJUUQvYmswQmIvbFRobVpYNm1EUTBrMWYKdmpCTm03UVNqK1dvMjRzRldYem5vd0loQUlqT2paTytuNnVqZmFRcUZ2cWgxWVB0TFR4alg3T3lNOU1NZml4QQpyaWhBCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
            key: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUE0aTluY21hTkJzMGtNR3hHM3hqUEpsajc2UmpOT0NtbjgrK3QrclVmU1JvQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFd0RiKzJCMlJRMHJoMVV2MnRUVVRBTTQ1Q09BWlh5YVJHNXBScVVSRjJnRThHaFVKaENzYgpiVi9Db01makZvd0VuU0tuNmVXN3luck4xdC95NS9MaERBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
        
        # # The container image used to create the etcd service.
        # image: gcr.io/etcd-development/etcd:v3.5.13

        # # The `advertisedSubnets` field configures the networks to pick etcd advertised IP from.
        # advertisedSubnets:
        #     - 10.0.0.0/8
    # A list of urls that point to additional manifests.
    extraManifests: []
    #   - https://www.example.com/manifest1.yaml
    #   - https://www.example.com/manifest2.yaml

    # A list of inline Kubernetes manifests.
    inlineManifests: []
    #   - name: namespace-ci # Name of the manifest.
    #     contents: |- # Manifest contents as a string.
    #       apiVersion: v1
    #       kind: Namespace
    #       metadata:
    #       	name: ci

    
    # # A key used for the [encryption of secret data at rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/).

    # # Decryption secret example (do not use in production!).
    # aescbcEncryptionSecret: z01mye6j16bspJYtTB/5SFX8j7Ph4JXxM2Xuu4vsBPM=

    # # Core DNS specific configuration options.
    # coreDNS:
    #     image: registry.k8s.io/coredns/coredns:v1.11.1 # The `image` field is an override to the default coredns image.

    # # External cloud provider configuration.
    # externalCloudProvider:
    #     enabled: true # Enable external cloud provider.
    #     # A list of urls that point to additional manifests for an external cloud provider.
    #     manifests:
    #         - https://raw.githubusercontent.com/kubernetes/cloud-provider-aws/v1.20.0-alpha.0/manifests/rbac.yaml
    #         - https://raw.githubusercontent.com/kubernetes/cloud-provider-aws/v1.20.0-alpha.0/manifests/aws-cloud-controller-manager-daemonset.yaml

    # # A map of key value pairs that will be added while fetching the extraManifests.
    # extraManifestHeaders:
    #     Token: "1234567"
    #     X-ExtraInfo: info

    # # Settings for admin kubeconfig generation.
    # adminKubeconfig:
    #     certLifetime: 1h0m0s # Admin kubeconfig certificate lifetime (default is 1 year).

    # # Allows running workload on control-plane nodes.
    # allowSchedulingOnControlPlanes: true
worker.yaml
version: v1alpha1 # Indicates the schema used to decode the contents.
debug: false # Enable verbose logging to the console.
persist: true
# Provides machine specific configuration options.
machine:
    type: worker # Defines the role of the machine within the cluster.
    token: toxf8p.zgsxaxqv9u1qnavn # The `token` is used by a machine to join the PKI of the cluster.
    # The root certificate authority of the PKI.
    ca:
        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJQekNCOHFBREFnRUNBaEVBLzVvL0R6M1poOHNtRERMNWZKUjZSekFGQmdNclpYQXdFREVPTUF3R0ExVUUKQ2hNRmRHRnNiM013SGhjTk1qUXdOakkyTVRjeE5qQXpXaGNOTXpRd05qSTBNVGN4TmpBeldqQVFNUTR3REFZRApWUVFLRXdWMFlXeHZjekFxTUFVR0F5dGxjQU1oQUNPRlhYdmM0NFdqZGh5R05oeWkwOXZVOXZZYTNqRU5GLzlXCm1CcUxIQVR6bzJFd1h6QU9CZ05WSFE4QkFmOEVCQU1DQW9Rd0hRWURWUjBsQkJZd0ZBWUlLd1lCQlFVSEF3RUcKQ0NzR0FRVUZCd01DTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkNmaFhsQmh3TzVnVEI0NQphbE9TTXhTaGxjeGVNQVVHQXl0bGNBTkJBS2tVZ0tqN1RTNmMzNmtXZ0JRMHVnRlB3djZ3N3F0RXJSR25OQjBsCjNTTWNCdnQ0VmFFSlIvSHpEblRFK2JjVmtBd0Z5WG5mNlJXV2tsb1pXMElweWdRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        key: ""
    # Extra certificate subject alternative names for the machine's certificate.
    certSANs: []
    #   # Uncomment this to enable SANs.
    #   - 10.0.0.10
    #   - 172.16.0.10
    #   - 192.168.0.10

    # Used to provide additional options to the kubelet.
    kubelet:
        image: ghcr.io/siderolabs/kubelet:v1.30.1 # The `image` field is an optional reference to an alternative kubelet image.
        defaultRuntimeSeccompProfileEnabled: true # Enable container runtime default Seccomp profile.
        disableManifestsDirectory: true # The `disableManifestsDirectory` field configures the kubelet to get static pod manifests from the /etc/kubernetes/manifests directory.
        
        # # The `ClusterDNS` field is an optional reference to an alternative kubelet clusterDNS ip list.
        # clusterDNS:
        #     - 10.96.0.10
        #     - 169.254.2.53

        # # The `extraArgs` field is used to provide additional flags to the kubelet.
        # extraArgs:
        #     key: value

        # # The `extraMounts` field is used to add additional mounts to the kubelet container.
        # extraMounts:
        #     - destination: /var/lib/example # Destination is the absolute path where the mount will be placed in the container.
        #       type: bind # Type specifies the mount kind.
        #       source: /var/lib/example # Source specifies the source path of the mount.
        #       # Options are fstab style mount options.
        #       options:
        #         - bind
        #         - rshared
        #         - rw

        # # The `extraConfig` field is used to provide kubelet configuration overrides.
        # extraConfig:
        #     serverTLSBootstrap: true

        # # The `KubeletCredentialProviderConfig` field is used to provide kubelet credential configuration.
        # credentialProviderConfig:
        #     apiVersion: kubelet.config.k8s.io/v1
        #     kind: CredentialProviderConfig
        #     providers:
        #         - apiVersion: credentialprovider.kubelet.k8s.io/v1
        #           defaultCacheDuration: 12h
        #           matchImages:
        #             - '*.dkr.ecr.*.amazonaws.com'
        #             - '*.dkr.ecr.*.amazonaws.com.cn'
        #             - '*.dkr.ecr-fips.*.amazonaws.com'
        #             - '*.dkr.ecr.us-iso-east-1.c2s.ic.gov'
        #             - '*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov'
        #           name: ecr-credential-provider

        # # The `nodeIP` field is used to configure `--node-ip` flag for the kubelet.
        # nodeIP:
        #     # The `validSubnets` field configures the networks to pick kubelet node IP from.
        #     validSubnets:
        #         - 10.0.0.0/8
        #         - '!10.0.0.3/32'
        #         - fdc7::/16
    # Provides machine specific network configuration options.
    network: 
    # # `interfaces` is used to define the network interface configuration.
    # interfaces:
    #     - interface: enp0s1 # The interface name.
    #       # Assigns static IP addresses to the interface.
    #       addresses:
    #         - 192.168.2.0/24
    #       # A list of routes associated with the interface.
    #       routes:
    #         - network: 0.0.0.0/0 # The route's network (destination).
    #           gateway: 192.168.2.1 # The route's gateway (if empty, creates link scope route).
    #           metric: 1024 # The optional metric for the route.
    #       mtu: 1500 # The interface's MTU.
    #       
    #       # # Picks a network device using the selector.

    #       # # select a device with bus prefix 00:*.
    #       # deviceSelector:
    #       #     busPath: 00:* # PCI, USB bus prefix, supports matching by wildcard.
    #       # # select a device with mac address matching `*:f0:ab` and `virtio` kernel driver.
    #       # deviceSelector:
    #       #     hardwareAddr: '*:f0:ab' # Device hardware address, supports matching by wildcard.
    #       #     driver: virtio # Kernel driver, supports matching by wildcard.
    #       # # select a device with bus prefix 00:*, a device with mac address matching `*:f0:ab` and `virtio` kernel driver.
    #       # deviceSelector:
    #       #     - busPath: 00:* # PCI, USB bus prefix, supports matching by wildcard.
    #       #     - hardwareAddr: '*:f0:ab' # Device hardware address, supports matching by wildcard.
    #       #       driver: virtio # Kernel driver, supports matching by wildcard.

    #       # # Bond specific options.
    #       # bond:
    #       #     # The interfaces that make up the bond.
    #       #     interfaces:
    #       #         - enp2s0
    #       #         - enp2s1
    #       #     # Picks a network device using the selector.
    #       #     deviceSelectors:
    #       #         - busPath: 00:* # PCI, USB bus prefix, supports matching by wildcard.
    #       #         - hardwareAddr: '*:f0:ab' # Device hardware address, supports matching by wildcard.
    #       #           driver: virtio # Kernel driver, supports matching by wildcard.
    #       #     mode: 802.3ad # A bond option.
    #       #     lacpRate: fast # A bond option.

    #       # # Bridge specific options.
    #       # bridge:
    #       #     # The interfaces that make up the bridge.
    #       #     interfaces:
    #       #         - enxda4042ca9a51
    #       #         - enxae2a6774c259
    #       #     # A bridge option.
    #       #     stp:
    #       #         enabled: true # Whether Spanning Tree Protocol (STP) is enabled.

    #       # # Indicates if DHCP should be used to configure the interface.
    #       # dhcp: true

    #       # # DHCP specific options.
    #       # dhcpOptions:
    #       #     routeMetric: 1024 # The priority of all routes received via DHCP.

    #       # # Wireguard specific configuration.

    #       # # wireguard server example
    #       # wireguard:
    #       #     privateKey: ABCDEF... # Specifies a private key configuration (base64 encoded).
    #       #     listenPort: 51111 # Specifies a device's listening port.
    #       #     # Specifies a list of peer configurations to apply to a device.
    #       #     peers:
    #       #         - publicKey: ABCDEF... # Specifies the public key of this peer.
    #       #           endpoint: 192.168.1.3 # Specifies the endpoint of this peer entry.
    #       #           # AllowedIPs specifies a list of allowed IP addresses in CIDR notation for this peer.
    #       #           allowedIPs:
    #       #             - 192.168.1.0/24
    #       # # wireguard peer example
    #       # wireguard:
    #       #     privateKey: ABCDEF... # Specifies a private key configuration (base64 encoded).
    #       #     # Specifies a list of peer configurations to apply to a device.
    #       #     peers:
    #       #         - publicKey: ABCDEF... # Specifies the public key of this peer.
    #       #           endpoint: 192.168.1.2:51822 # Specifies the endpoint of this peer entry.
    #       #           persistentKeepaliveInterval: 10s # Specifies the persistent keepalive interval for this peer.
    #       #           # AllowedIPs specifies a list of allowed IP addresses in CIDR notation for this peer.
    #       #           allowedIPs:
    #       #             - 192.168.1.0/24

    #       # # Virtual (shared) IP address configuration.

    #       # # layer2 vip example
    #       # vip:
    #       #     ip: 172.16.199.55 # Specifies the IP address to be used.

    # # Used to statically set the nameservers for the machine.
    # nameservers:
    #     - 8.8.8.8
    #     - 1.1.1.1

    # # Allows for extra entries to be added to the `/etc/hosts` file
        extraHostEntries:
        - ip: 192.168.2.140
          aliases:
          - k8s-talos-cp01
        - ip: 192.168.2.141
          aliases:
          - k8s-talos-node01
        - ip: 192.168.2.142
          aliases:
          - k8s-talos-node02

    # # Configures KubeSpan feature.
    # kubespan:
    #     enabled: true # Enable the KubeSpan feature.

    # Used to provide instructions for installations.
    install:
        disk: /dev/sda # The disk used for installations.
        image: ghcr.io/siderolabs/installer:v1.7.5 # Allows for supplying the image used to perform the installation.
        wipe: false # Indicates if the installation disk should be wiped at installation time.
        
        # # Look up disk using disk attributes like model, size, serial and others.
        # diskSelector:
        #     size: 4GB # Disk size.
        #     model: WDC* # Disk model `/sys/block/<dev>/device/model`.
        #     busPath: /pci0000:00/0000:00:17.0/ata1/host0/target0:0:0/0:0:0:0 # Disk bus path.

        # # Allows for supplying extra kernel args via the bootloader.
        # extraKernelArgs:
        #     - talos.platform=metal
        #     - reboot=k

        # # Allows for supplying additional system extension images to install on top of base Talos image.
        # extensions:
        #     - image: ghcr.io/siderolabs/gvisor:20220117.0-v1.0.0 # System extension image.
    # Used to configure the machine's container image registry mirrors.
    registries: {}
    # # Specifies mirror configuration for each registry host namespace.
    # mirrors:
    #     ghcr.io:
    #         # List of endpoints (URLs) for registry mirrors to use.
    #         endpoints:
    #             - https://registry.insecure
    #             - https://ghcr.io/v2/

    # # Specifies TLS & auth configuration for HTTPS image registries.
    # config:
    #     registry.insecure:
    #         # The TLS configuration for the registry.
    #         tls:
    #             insecureSkipVerify: true # Skip TLS server certificate verification (not recommended).
    #             
    #             # # Enable mutual TLS authentication with the registry.
    #             # clientIdentity:
    #             #     crt: LS0tIEVYQU1QTEUgQ0VSVElGSUNBVEUgLS0t
    #             #     key: LS0tIEVYQU1QTEUgS0VZIC0tLQ==
    #         
    #         # # The auth configuration for this registry.
    #         # auth:
    #         #     username: username # Optional registry authentication.
    #         #     password: password # Optional registry authentication.

    # Features describe individual Talos features that can be switched on or off.
    features:
        rbac: true # Enable role-based access control (RBAC).
        stableHostname: true # Enable stable default hostname.
        apidCheckExtKeyUsage: true # Enable checks for extended key usage of client certificates in apid.
        diskQuotaSupport: true # Enable XFS project quota support for EPHEMERAL partition and user disks.
        # KubePrism - local proxy/load balancer on defined port that will distribute
        kubePrism:
            enabled: true # Enable KubePrism support - will start local load balancing proxy.
            port: 7445 # KubePrism port.
        # Configures host DNS caching resolver.
        hostDNS:
            enabled: true # Enable host DNS caching resolver.
        
        # # Configure Talos API access from Kubernetes pods.
        # kubernetesTalosAPIAccess:
        #     enabled: true # Enable Talos API access from Kubernetes pods.
        #     # The list of Talos API roles which can be granted for access from Kubernetes pods.
        #     allowedRoles:
        #         - os:reader
        #     # The list of Kubernetes namespaces Talos API access is available from.
        #     allowedKubernetesNamespaces:
        #         - kube-system
    
    # # Provides machine specific control plane configuration options.

    # # ControlPlane definition example.
    # controlPlane:
    #     # Controller manager machine specific configuration options.
    #     controllerManager:
    #         disabled: false # Disable kube-controller-manager on the node.
    #     # Scheduler machine specific configuration options.
    #     scheduler:
    #         disabled: true # Disable kube-scheduler on the node.

    # # Used to provide static pod definitions to be run by the kubelet directly bypassing the kube-apiserver.

    # # nginx static pod.
    # pods:
    #     - apiVersion: v1
    #       kind: pod
    #       metadata:
    #         name: nginx
    #       spec:
    #         containers:
    #             - image: nginx
    #               name: nginx

    # # Used to partition, format and mount additional disks.

    # # MachineDisks list example.
    # disks:
    #     - device: /dev/sdb # The name of the disk to use.
    #       # A list of partitions to create on the disk.
    #       partitions:
    #         - mountpoint: /var/mnt/extra # Where to mount the partition.
    #           
    #           # # The size of partition: either bytes or human readable representation. If `size:` is omitted, the partition is sized to occupy the full disk.

    #           # # Human readable representation.
    #           # size: 100 MB
    #           # # Precise value in bytes.
    #           # size: 1073741824

    # # Allows the addition of user specified files.

    # # MachineFiles usage example.
    # files:
    #     - content: '...' # The contents of the file.
    #       permissions: 0o666 # The file's permissions in octal.
    #       path: /tmp/file.txt # The path of the file.
    #       op: append # The operation to use

    # # The `env` field allows for the addition of environment variables.

    # # Environment variables definition examples.
    # env:
    #     GRPC_GO_LOG_SEVERITY_LEVEL: info
    #     GRPC_GO_LOG_VERBOSITY_LEVEL: "99"
    #     https_proxy: http://SERVER:PORT/
    # env:
    #     GRPC_GO_LOG_SEVERITY_LEVEL: error
    #     https_proxy: https://USERNAME:PASSWORD@SERVER:PORT/
    # env:
    #     https_proxy: http://DOMAIN\USERNAME:PASSWORD@SERVER:PORT/

    # # Used to configure the machine's time settings.

    # # Example configuration for cloudflare ntp server.
    # time:
    #     disabled: false # Indicates if the time service is disabled for the machine.
    #     # description: |
    #     servers:
    #         - time.cloudflare.com
    #     bootTimeout: 2m0s # Specifies the timeout when the node time is considered to be in sync unlocking the boot sequence.

    # # Used to configure the machine's sysctls.

    # # MachineSysctls usage example.
    # sysctls:
    #     kernel.domainname: talos.dev
    #     net.ipv4.ip_forward: "0"
    #     net/ipv6/conf/eth0.100/disable_ipv6: "1"

    # # Used to configure the machine's sysfs.

    # # MachineSysfs usage example.
    # sysfs:
    #     devices.system.cpu.cpu0.cpufreq.scaling_governor: performance

    # # Machine system disk encryption configuration.
    # systemDiskEncryption:
    #     # Ephemeral partition encryption.
    #     ephemeral:
    #         provider: luks2 # Encryption provider to use for the encryption.
    #         # Defines the encryption keys generation and storage method.
    #         keys:
    #             - # Deterministically generated key from the node UUID and PartitionLabel.
    #               nodeID: {}
    #               slot: 0 # Key slot number for LUKS2 encryption.
    #               
    #               # # KMS managed encryption key.
    #               # kms:
    #               #     endpoint: https://192.168.88.21:4443 # KMS endpoint to Seal/Unseal the key.
    #         
    #         # # Cipher kind to use for the encryption. Depends on the encryption provider.
    #         # cipher: aes-xts-plain64

    #         # # Defines the encryption sector size.
    #         # blockSize: 4096

    #         # # Additional --perf parameters for the LUKS2 encryption.
    #         # options:
    #         #     - no_read_workqueue
    #         #     - no_write_workqueue

    # # Configures the udev system.
    # udev:
    #     # List of udev rules to apply to the udev system
    #     rules:
    #         - SUBSYSTEM=="drm", KERNEL=="renderD*", GROUP="44", MODE="0660"

    # # Configures the logging system.
    # logging:
    #     # Logging destination.
    #     destinations:
    #         - endpoint: tcp://1.2.3.4:12345 # Where to send logs. Supported protocols are "tcp" and "udp".
    #           format: json_lines # Logs format.

    # # Configures the kernel.
    # kernel:
    #     # Kernel modules to load.
    #     modules:
    #         - name: brtfs # Module name.

    # # Configures the seccomp profiles for the machine.
    # seccompProfiles:
    #     - name: audit.json # The `name` field is used to provide the file name of the seccomp profile.
    #       # The `value` field is used to provide the seccomp profile.
    #       value:
    #         defaultAction: SCMP_ACT_LOG

    # # Configures the node labels for the machine.

    # # node labels example.
    # nodeLabels:
    #     exampleLabel: exampleLabelValue

    # # Configures the node taints for the machine. Effect is optional.

    # # node taints example.
    # nodeTaints:
    #     exampleTaint: exampleTaintValue:NoSchedule
# Provides cluster specific configuration options.
cluster:
    id: BWUQjnVv7QnZOkH-L1x41CIWXqtEo2PFcJeqooSwfnI= # Globally unique identifier for this cluster (base64 encoded random 32 bytes).
    secret: 8fLzwGc0HJbFSCZazQr8NRQToVFosXu2M8n0eFgiZF4= # Shared secret of cluster (base64 encoded random 32 bytes).
    # Provides control plane specific configuration options.
    controlPlane:
        endpoint: https://k8s-talos-cp01:6443 # Endpoint is the canonical controlplane endpoint, which can be an IP address or a DNS hostname.
    # Provides cluster specific network configuration options.
    network:
        dnsDomain: cluster.local # The domain used by Kubernetes DNS.
        # The pod subnet CIDR.
        podSubnets:
            - 10.244.0.0/16
        # The service subnet CIDR.
        serviceSubnets:
            - 10.96.0.0/12
        
        # # The CNI used.
        cni: 
          name: none
        #     # URLs containing manifests to apply for the CNI.
        #     urls:
        #         - https://docs.projectcalico.org/archive/v3.20/manifests/canal.yaml
    token: u7iftl.y6gon6nukk202arm # The [bootstrap token](https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/) used to join the cluster.
    # The base64 encoded root certificate authority used by Kubernetes.
    ca:
        crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpVENDQVRDZ0F3SUJBZ0lSQU5yQ0Ywa2RtQ2ZIRXBVY2RCOXlYNjB3Q2dZSUtvWkl6ajBFQXdJd0ZURVQKTUJFR0ExVUVDaE1LYTNWaVpYSnVaWFJsY3pBZUZ3MHlOREEyTWpZeE56RTJNRE5hRncwek5EQTJNalF4TnpFMgpNRE5hTUJVeEV6QVJCZ05WQkFvVENtdDFZbVZ5Ym1WMFpYTXdXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CCkJ3TkNBQVIzVU9GN09NRjEvbDQ4UmdFRjQxVDgrZWJCYzB6K0doUTRSd2dpK0RMRHhkVVo1OUFoZUNlQTl6alYKUURma084Zk1YTnQ1RXkwM0tTMVNNdUlhWm80S28yRXdYekFPQmdOVkhROEJBZjhFQkFNQ0FvUXdIUVlEVlIwbApCQll3RkFZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0hRWURWUjBPCkJCWUVGQWVKYW5ic0IvdmErU2xpM0luelpzUkx2TjhwTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUJxMEJUVVgKVWo1QjRNUEhVNUsxUTZ0SUVoQlVXWjZTM3lYTFBKYUttWXZLQWlCd2J6SzRCV1hOVXNWNlV3dWVuZEQrQ2MxSAp6cDJkK090aFlXRVIxRDVuZ1E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
        key: ""
    # Configures cluster member discovery.
    discovery:
        enabled: true # Enable the cluster membership discovery feature.
        # Configure registries used for cluster member discovery.
        registries:
            # Kubernetes registry uses Kubernetes API server to discover cluster members and stores additional information
            kubernetes:
                disabled: true # Disable Kubernetes discovery registry.
            # Service registry is using an external service to push and pull information about cluster members.
            service: {}
            # # External service endpoint.
            # endpoint: https://discovery.talos.dev/
    
    # # A key used for the [encryption of secret data at rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/).

    # # Decryption secret example (do not use in production!).
    # aescbcEncryptionSecret: z01mye6j16bspJYtTB/5SFX8j7Ph4JXxM2Xuu4vsBPM=

    # # A key used for the [encryption of secret data at rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/).

    # # Decryption secret example (do not use in production!).
    # secretboxEncryptionSecret: z01mye6j16bspJYtTB/5SFX8j7Ph4JXxM2Xuu4vsBPM=

    # # The base64 encoded aggregator certificate authority used by Kubernetes for front-proxy certificate generation.

    # # AggregatorCA example.
    # aggregatorCA:
    #     crt: LS0tIEVYQU1QTEUgQ0VSVElGSUNBVEUgLS0t
    #     key: LS0tIEVYQU1QTEUgS0VZIC0tLQ==

    # # The base64 encoded private key for service account token generation.

    # # AggregatorCA example.
    # serviceAccount:
    #     key: LS0tIEVYQU1QTEUgS0VZIC0tLQ==

    # # API server specific configuration options.
    # apiServer:
    #     image: registry.k8s.io/kube-apiserver:v1.30.1 # The container image used in the API server manifest.
    #     # Extra arguments to supply to the API server.
    #     extraArgs:
    #         feature-gates: ServerSideApply=true
    #         http2-max-streams-per-connection: "32"
    #     # Extra certificate subject alternative names for the API server's certificate.
    #     certSANs:
    #         - 1.2.3.4
    #         - 4.5.6.7
    #     # Configure the API server admission plugins.
    #     admissionControl:
    #         - name: PodSecurity # Name is the name of the admission controller.
    #           # Configuration is an embedded configuration object to be used as the plugin's
    #           configuration:
    #             apiVersion: pod-security.admission.config.k8s.io/v1alpha1
    #             defaults:
    #                 audit: restricted
    #                 audit-version: latest
    #                 enforce: baseline
    #                 enforce-version: latest
    #                 warn: restricted
    #                 warn-version: latest
    #             exemptions:
    #                 namespaces:
    #                     - kube-system
    #                 runtimeClasses: []
    #                 usernames: []
    #             kind: PodSecurityConfiguration
    #     # Configure the API server audit policy.
    #     auditPolicy:
    #         apiVersion: audit.k8s.io/v1
    #         kind: Policy
    #         rules:
    #             - level: Metadata

    # # Controller manager server specific configuration options.
    # controllerManager:
    #     image: registry.k8s.io/kube-controller-manager:v1.30.1 # The container image used in the controller manager manifest.
    #     # Extra arguments to supply to the controller manager.
    #     extraArgs:
    #         feature-gates: ServerSideApply=true

    # # Kube-proxy server-specific configuration options
    # proxy:
    #     disabled: false # Disable kube-proxy deployment on cluster bootstrap.
    #     image: registry.k8s.io/kube-proxy:v1.30.1 # The container image used in the kube-proxy manifest.
    #     mode: ipvs # proxy mode of kube-proxy.
    #     # Extra arguments to supply to kube-proxy.
    #     extraArgs:
    #         proxy-mode: iptables

    # # Scheduler server specific configuration options.
    # scheduler:
    #     image: registry.k8s.io/kube-scheduler:v1.30.1 # The container image used in the scheduler manifest.
    #     # Extra arguments to supply to the scheduler.
    #     extraArgs:
    #         feature-gates: AllBeta=true

    # # Etcd specific configuration options.
    # etcd:
    #     image: gcr.io/etcd-development/etcd:v3.5.13 # The container image used to create the etcd service.
    #     # The `ca` is the root certificate authority of the PKI.
    #     ca:
    #         crt: LS0tIEVYQU1QTEUgQ0VSVElGSUNBVEUgLS0t
    #         key: LS0tIEVYQU1QTEUgS0VZIC0tLQ==
    #     # Extra arguments to supply to etcd.
    #     extraArgs:
    #         election-timeout: "5000"
    #     # The `advertisedSubnets` field configures the networks to pick etcd advertised IP from.
    #     advertisedSubnets:
    #         - 10.0.0.0/8

    # # Core DNS specific configuration options.
    # coreDNS:
    #     image: registry.k8s.io/coredns/coredns:v1.11.1 # The `image` field is an override to the default coredns image.

    # # External cloud provider configuration.
    # externalCloudProvider:
    #     enabled: true # Enable external cloud provider.
    #     # A list of urls that point to additional manifests for an external cloud provider.
    #     manifests:
    #         - https://raw.githubusercontent.com/kubernetes/cloud-provider-aws/v1.20.0-alpha.0/manifests/rbac.yaml
    #         - https://raw.githubusercontent.com/kubernetes/cloud-provider-aws/v1.20.0-alpha.0/manifests/aws-cloud-controller-manager-daemonset.yaml

    # # A list of urls that point to additional manifests.
    # extraManifests:
    #     - https://www.example.com/manifest1.yaml
    #     - https://www.example.com/manifest2.yaml

    # # A map of key value pairs that will be added while fetching the extraManifests.
    # extraManifestHeaders:
    #     Token: "1234567"
    #     X-ExtraInfo: info

    # # A list of inline Kubernetes manifests.
    # inlineManifests:
    #     - name: namespace-ci # Name of the manifest.
    #       contents: |- # Manifest contents as a string.
    #         apiVersion: v1
    #         kind: Namespace
    #         metadata:
    #         	name: ci

    # # Settings for admin kubeconfig generation.
    # adminKubeconfig:
    #     certLifetime: 1h0m0s # Admin kubeconfig certificate lifetime (default is 1 year).

    # # Allows running workload on control-plane nodes.
    # allowSchedulingOnControlPlanes: true

Kubernetesクラスタの構築

先ほど用意したmachine configを使用して、各サーバーに設定を適用します。

$ talosctl apply-config --insecure -n k8s-talos-cp01 --file controlplane.yaml
$ talosctl apply-config --insecure -n k8s-talos-node01 --file worker.yaml
$ talosctl apply-config --insecure -n k8s-talos-node02 --file worker.yaml

このコマンドを実行すると、サーバーの再起動が行われます。(サーバーのコンソールから実際に再起動が行われる様子が確認できます。)
なお、これ以降各サーバーをtalosctlで操作する(APIにアクセスする)場合は--talosconfig=./talosconfigというオプションを付与することで、talosconfigに記載された認証情報を使用する必要があります。

再起動が完了したら、Control Planeのサーバーに対して次のコマンドを実行し、Kubernetesクラスタを構築します。

$ talosctl bootstrap --nodes k8s-talos-cp01 --endpoints k8s-talos-cp01 --talosconfig=./talosconfig

なお上記では--nodesおよび--endpointsというフラグを指定していますが、これらについては次の記事で解説します。
ここでは両フラグでk8s-talos-cp01を指定します。

上記コマンドを実行して暫く経つと、Control Planeのコンソール上でAPISERVERのステータスがHealthyに変わります。

APISERVERのステータスがHealthyになったことを確認したら、Kubernetesクラスタの認証情報を含むkubeconfigを取得します。
ここではalternative-kubeconfigというファイル名でkubeconfigを取得しています。

$ talosctl kubeconfig alternative-kubeconfig --nodes k8s-talos-cp01 --endpoints k8s-talos-cp01 --talosconfig=./talosconfig

kubeconfigを取得したら、Kubernetesクラスタを構成するNodeの状態を確認します。
現時点ではまだCNI Pluginのインストールを行っていないため、全てのNodeがNotReadyになっています。

$ kubectl --kubeconfig ./alternative-kubeconfig get node -owide
NAME               STATUS     ROLES           AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION   CONTAINER-RUNTIME
k8s-talos-cp01     NotReady   control-plane   2m50s   v1.30.1   192.168.2.140   <none>        Talos (v1.7.5)   6.6.33-talos     containerd://1.7.18
k8s-talos-node01   NotReady   <none>          2m50s   v1.30.1   192.168.2.141   <none>        Talos (v1.7.5)   6.6.33-talos     containerd://1.7.18
k8s-talos-node02   NotReady   <none>          2m48s   v1.30.1   192.168.2.142   <none>        Talos (v1.7.5)   6.6.33-talos     containerd://1.7.18

今回はCNI Pluginとしてcalicoを使用するため、公式ドキュメントの手順に従ってインストールします。

https://docs.tigera.io/calico/latest/getting-started/kubernetes/self-managed-onprem/onpremises

controlplane.yamlおよびworker.yaml.cluster.network.podSubnetsで指定されているPodのネットワークレンジと、calicoインストール時に指定するPodのネットワークレンジを一致させる必要がある点に注意してください。
今回の手順ではcustom-resources.yamlで指定を行っています。

custom-resources.yaml
# This section includes base Calico installation configuration.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # Configures Calico networking.
  calicoNetwork:
    # Note: The ipPools section cannot be modified post-install.
    ipPools:
    - blockSize: 26
      cidr: 10.244.0.0/16
$ kubectl --kubeconfig ./alternative-kubeconfig create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/tigera-operator.yaml

$ kubectl --kubeconfig ./alternative-kubeconfig create -f custom-resources.yaml

calicoのインストールが完了すると、Nodeのステータスが全てReadyになります。
これでKubernetesクラスタの構築は完了です。

$ kubectl --kubeconfig ./alternative-kubeconfig get node -owide
NAME               STATUS   ROLES           AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION   CONTAINER-RUNTIME
k8s-talos-cp01     Ready    control-plane   4m38s   v1.30.1   192.168.2.140   <none>        Talos (v1.7.5)   6.6.33-talos     containerd://1.7.18
k8s-talos-node01   Ready    <none>          4m38s   v1.30.1   192.168.2.141   <none>        Talos (v1.7.5)   6.6.33-talos     containerd://1.7.18
k8s-talos-node02   Ready    <none>          4m36s   v1.30.1   192.168.2.142   <none>        Talos (v1.7.5)   6.6.33-talos     containerd://1.7.18

なお、KubernetesクラスタやTalos Linuxそのものに関するアップグレードもtalosctlを用いて行うことができるようです。

https://www.talos.dev/v1.7/kubernetes-guides/upgrading-kubernetes/

https://www.talos.dev/v1.7/talos-guides/upgrading-talos/

続く。
https://zenn.dev/mochizuki875/articles/43c65c91505419

Discussion