手当たり次第に書くんだ

飽きっぽいのは本能

Ubuntu 22.04 Kubernetes クラスター構築

目次に戻る

Overview

Kubernetes クラスターを構築します。

前提条件

  • こちらを参考に containerd の環境構築が完了していること。
  • こちらを参考に「Kubernetes クラスター構築の事前準備」が完了していること。
  • 本稿の Kubernetes クラスターは、Master ノード x1、Worker ノード x1 の構成です。Worker ノードはこの手順を参考に追加可能ですが、Master ノードを複数構築する場合は個別にロードバランサーが必要となります。ロードバランサーは種類を問いませんが、OSS であれば HAProxy がよく使用されます。
  • 本稿の Kubernetes クラスターは、IPv4/IPv6 DualStack を前提としているため、通常に比べ、若干複雑になっています。特に IPv6 のサイズは Kubernetes, CNI ともに制約があり、試しながら適切なサイズをアサインする必要があります。IPv6 が不要なら、各マニフェストから IPv6 を除くだけで動くと思います。
  • Kubernetes クラスターの構築は、Master ノード、Worker ノードのそれぞれで操作が必要になるため、各手順にどちらで実施する操作であるかを記載しています。
  • CNI に Calico を選定しています。Calico は CNI としてデファクトスタンダードに近く、多くのマネージド Kubernetes でも採用されています。他には、flannel や Kube-OVN など、多くの CNI が存在しています。
  • Calico は BGP でも動作しますが、本稿では使用していません。
  • ステータスの出力情報はサンプルであり、名前などの一貫性がない場合があります。

kubeadm init

Master ノード: ${HOME}/work/k8s/kubeadm-config.yaml を作成します。

myadmin@ubuntu-22-04:~$ tee ${HOME}/work/k8s/kubeadm-config.yaml <<"EOF"
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
clusterName: s00-int-k8s-cluster-n001.si1230.com
networking:
  podSubnet: 10.129.0.0/21,fd02::/64
  serviceSubnet: 10.129.32.0/21,fd03::/108
controlPlaneEndpoint: s00-int-k8s-cluster-n001.si1230.com:6443
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 10.1.0.180
  bindPort: 6443
nodeRegistration:
  kubeletExtraArgs:
    node-ip: 10.1.0.180,fd00::a01:b4
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true
EOF
  1. ClusterConfiguration:
    • apiVersion: kubeadm.k8s.io/v1beta3: 使用している API バージョン。
    • kind: ClusterConfiguration: このリソースの種類を示します。
    • clusterName: クラスターの名前。
    • networking: ネットワーキングに関連する設定を含みます。
      • podSubnet: Pod が使用するサブネットを指定します。ここでは IPv4 と IPv6 のアドレス範囲が指定されています。
      • serviceSubnet: Kubernetes サービスが使用するサブネット。IPv4 と IPv6 の範囲も指定されています。
  2. InitConfiguration:
    • apiVersion: kubeadm.k8s.io/v1beta3: 使用している API バージョン。
    • kind: InitConfiguration: このリソースの種類を示します。
    • localAPIEndpoint: API サーバーのエンドポイント設定。
      • advertiseAddress: クラスタ内の他のコンポーネントがこの Master ノードを見つけるために使用する IP アドレス。
      • bindPort: Kubernetes API サーバーがリッスンするポート(通常は 6443)。
    • nodeRegistration: ノード登録時の追加設定。
      • kubeletExtraArgs: kubelet の追加コマンドライン引数。
        • node-ip: ノードに割り当てられた IP アドレス。IPv4 と IPv6 のアドレスが指定されています。
  3. KubeletConfiguration:
    • apiVersion: kubelet.config.k8s.io/v1beta1: Kubelet 設定の API バージョン。
    • kind: KubeletConfiguration: このリソースの種類を示します。
    • cgroupDriver: Kubernetes が使用する cgroup ドライバー。ここでは systemd を指定しており、この設定は containerd の設定と合わせる必要があります。

Master ノード: kubeadm init を実行し、クラスターを作成します。

myadmin@ubuntu-22-04:~$ sudo kubeadm init --config=${HOME}/work/k8s/kubeadm-config.yaml --upload-certs

成功すると以下のように出力されます。

I0520 22:06:52.020398   13521 version.go:256] remote version is much newer: v1.30.1; falling back to: stable-1.29
[init] Using Kubernetes version: v1.29.5
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
W0520 22:06:52.685971   13521 checks.go:835] detected that the sandbox image "registry.k8s.io/pause:3.8" of the container runtime is inconsistent with that used by kubeadm. It is recommended that using "registry.k8s.io/pause:3.9" as the CRI sandbox image.
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local s00-int-k8s-cluster-n001.si1230.com s00-int-k8s-master-v001] and IPs [10.129.32.1 10.1.0.180]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost s00-int-k8s-master-v001] and IPs [10.1.0.180 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost s00-int-k8s-master-v001] and IPs [10.1.0.180 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "super-admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 4.024414 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
e5f5e4c5903a64eebb5fbaf13e301e37bb1169a53a0364713d1667f3b4ae3af7
[mark-control-plane] Marking the node s00-int-k8s-master-v001 as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node s00-int-k8s-master-v001 as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: p6hx1h.38roeyfwyka0mkfe
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join s00-int-k8s-cluster-n001.si1230.com:6443 --token p6hx1h.38roeyfwyka0mkfe \
	--discovery-token-ca-cert-hash sha256:903bf0263a878d364112455ddfbe8c2b5a9f672faf6bd2aba61ce3372c40bdd4 \
	--control-plane --certificate-key e5f5e4c5903a64eebb5fbaf13e301e37bb1169a53a0364713d1667f3b4ae3af7

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join s00-int-k8s-cluster-n001.si1230.com:6443 --token p6hx1h.38roeyfwyka0mkfe \
	--discovery-token-ca-cert-hash sha256:903bf0263a878d364112455ddfbe8c2b5a9f672faf6bd2aba61ce3372c40bdd4

Master ノード: kubeadm init が成功した際の出力にも記載されていますが、以下のようにクレデンシャルファイルを設定します。これにより、Master ノードから kubectl コマンドを実行できるようになります。

myadmin@ubuntu-22-04:~$ mkdir -p ${HOME}/.kube && sudo cp /etc/kubernetes/admin.conf ${HOME}/.kube/config && sudo chown $(id -u):$(id -g) ${HOME}/.kube/config

Master ノード: kubectl get node でノードの状態を確認します。CNI が存在しない状態では NotReady になります。

NAME                      STATUS      ROLES           AGE     VERSION
s00-int-k8s-master-v001   NotReady    control-plane   2m42s   v1.29.5

Master ノード: kubectl get pods -A で Pod の状態を確認します。CNI が存在しない状態では coredns が起動しません。

NAMESPACE     NAME                                              READY   STATUS              RESTARTS   AGE
kube-system   coredns-76f75df574-b8w2f                          0/1     ContainerCreating   0          4m20s
kube-system   coredns-76f75df574-fbd99                          0/1     ContainerCreating   0          4m20s
kube-system   etcd-s00-int-k8s-master-v001                      1/1     Running             6          4m34s
kube-system   kube-apiserver-s00-int-k8s-master-v001            1/1     Running             1          4m34s
kube-system   kube-controller-manager-s00-int-k8s-master-v001   1/1     Running             4          4m34s
kube-system   kube-proxy-xsscq                                  1/1     Running             0          4m21s
kube-system   kube-scheduler-s00-int-k8s-master-v001            1/1     Running             4          4m34s

CNI のインストール

Master ノード: CNI (Container Network Interface) をインストールします。本稿では Calico を使用します。

myadmin@ubuntu-22-04:~$ kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml

Master ノード: Calico を設定します。問題なければ、この時点で各 Pod の状態が正常になります。

myadmin@ubuntu-22-04:~$ cat <<EOF | kubectl create -f -
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  calicoNetwork:
    ipPools:
      - blockSize: 24
        cidr: 10.129.0.0/21
        encapsulation: None
        natOutgoing: Enabled
        nodeSelector: all()
      - blockSize: 116
        cidr: fd02::/64
        encapsulation: None
        natOutgoing: Enabled
        nodeSelector: all()
EOF
  • Installation:
    • apiVersion: operator.tigera.io/v1: 使用している API バージョン。
    • kind: Installation: このリソースの種類を示します。Calico のインストールを行う設定です。
    • metadata:
      • name: default: この設定の名前。デフォルトの設定として適用されます。
    • spec:
      • calicoNetwork:
        • ipPools: 使用する IP プールの設定。
          • blockSize: 24: IPv4 アドレスプールのブロックサイズ。サブネットマスクのビット数を示します。
            • cidr: 10.129.0.0/21: Pod に割り当てられる IPv4 アドレスの範囲。
            • encapsulation: None: IP パケットのカプセル化を行わない設定です。パフォーマンスを最適化するために、オーバーレイネットワークを使用しません。
            • natOutgoing: Enabled: NAT を有効にし、クラスター内のプライベートアドレスから外部への通信時にノードの IP アドレスを使用します。
            • nodeSelector: all(): この IP プールをクラスター内のすべてのノードで使用する設定です。
          • blockSize: 116: IPv6 アドレスプールのブロックサイズ。
            • cidr: fd02::/64: Pod に割り当てられる IPv6 アドレスの範囲。
            • encapsulation: None: IPv6 においてもカプセル化は行わず、オーバーレイネットワークを使用しません。
            • natOutgoing: Enabled: IPv6 アドレスに対しても NAT を有効にし、外部通信を可能にします。
            • nodeSelector: all(): この IPv6 アドレスプールもクラスター内の全ノードで使用します。

Master ノード: kubectl get node でノードの状態を確認します。CNI をインストールすることで Ready になります。

NAME                      STATUS   ROLES           AGE     VERSION
s00-int-k8s-master-v001   Ready    control-plane   9m58s   v1.29.5

Master ノード: kubectl get pods -A で Pod の状態を確認します。CNI をインストールすることで coredns が起動します。

NAMESPACE         NAME                                              READY   STATUS    RESTARTS   AGE
calico-system     calico-kube-controllers-c45bddc79-qwkr2           1/1     Running   0          64s
calico-system     calico-node-4wnfj                                 1/1     Running   0          64s
calico-system     calico-typha-9f64f5f44-4trst                      1/1     Running   0          64s
calico-system     csi-node-driver-q6q4l                             2/2     Running   0          64s
kube-system       coredns-76f75df574-b8w2f                          1/1     Running   0          10m
kube-system       coredns-76f75df574-fbd99                          1/1     Running   0          10m
kube-system       etcd-s00-int-k8s-master-v001                      1/1     Running   6          10m
kube-system       kube-apiserver-s00-int-k8s-master-v001            1/1     Running   1          10m
kube-system       kube-controller-manager-s00-int-k8s-master-v001   1/1     Running   4          10m
kube-system       kube-proxy-xsscq                                  1/1     Running   0          10m
kube-system       kube-scheduler-s00-int-k8s-master-v001            1/1     Running   4          10m
tigera-operator   tigera-operator-55585899bf-7mjds                  1/1     Running   0          97s

kubeadm join

Master ノード: Worker ノードの追加に必要となるトークンを出力させます。この情報は kubeadm init の出力で得られる情報と同じです。

myadmin@ubuntu-22-04:~$ kubeadm token create --print-join-command

Worker ノード: kubeadm join で Kubernetes クラスターに参加します。

myadmin@ubuntu-22-04:~$ sudo kubeadm join 10.1.0.180:6443 --token [token] --discovery-token-ca-cert-hash sha256:[sha256]

Master ノード: kubectl get node でノードの状態を確認します。Worker ノードが追加されたことを確認できます。

NAME                      STATUS   ROLES           AGE   VERSION
s00-int-k8s-master-v001   Ready    control-plane   21m   v1.29.5
s00-int-k8s-worker-v001   Ready    <none>          78s   v1.29.5

Master ノード: kubectl get pods -A で Pod の状態を確認します。calico-node が増えたことが確認できます。

NAMESPACE         NAME                                              READY   STATUS    RESTARTS   AGE
calico-system     calico-kube-controllers-c45bddc79-qwkr2           1/1     Running   0          12m
calico-system     calico-node-4wnfj                                 1/1     Running   0          12m
calico-system     calico-node-89bj2                                 1/1     Running   0          99s
calico-system     calico-typha-9f64f5f44-4trst                      1/1     Running   0          12m
calico-system     csi-node-driver-22kq6                             2/2     Running   0          99s
calico-system     csi-node-driver-q6q4l                             2/2     Running   0          12m
kube-system       coredns-76f75df574-b8w2f                          1/1     Running   0          21m
kube-system       coredns-76f75df574-fbd99                          1/1     Running   0          21m
kube-system       etcd-s00-int-k8s-master-v001                      1/1     Running   6          21m
kube-system       kube-apiserver-s00-int-k8s-master-v001            1/1     Running   1          21m
kube-system       kube-controller-manager-s00-int-k8s-master-v001   1/1     Running   4          21m
kube-system       kube-proxy-kv6zd                                  1/1     Running   0          99s
kube-system       kube-proxy-xsscq                                  1/1     Running   0          21m
kube-system       kube-scheduler-s00-int-k8s-master-v001            1/1     Running   4          21m
tigera-operator   tigera-operator-55585899bf-7mjds                  1/1     Running   0          12m

MetalLB

MetalLB をインストールします。

myadmin@ubuntu-22-04:~$ kubectl create -f https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-frr.yaml

MetalLB を設定します。本稿では L2 モードの設定となります。

myadmin@ubuntu-22-04:~$ cat <<EOF | kubectl create -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default
  namespace: metallb-system
spec:
  addresses:
    - 10.1.0.192/27
    - fd00::a01:c0/123
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
    - default
EOF
目次に戻る
Ubuntu 22.04 Kubernetes クラスター構築

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る