DUICUO

kubeadm は Kubernetes クラスターをデプロイし、コンテナ ランタイムとして containerd を使用します。

[[389249]]

序文

昨年12月、KubernetesコミュニティがDockershimをバージョン1.20以降段階​​的に廃止すると発表した際、多くのセルフメディアもKubernetesがDockerを放棄するだろうという説を宣伝しました。しかし、これは誤解を招く表現であり、人気の波に乗ろうとしただけのものかもしれません。

DockershimはKubernetesのコンポーネントであり、Dockerコンテナを操作するために設計されています。Dockerは2013年にリリースされましたが、Kubernetesは2016年にリリースされました。そのため、Dockerは当初オーケストレーションを想定しておらず、Kubernetesのような巨大な存在の出現も予見していませんでした(もし予見していたら、これほど早く衰退することはなかったでしょう…)。しかし、KubernetesはDockerをコンテナランタイムとして構築され、その運用ロジックの多くはDocker指向でした。コミュニティが成長するにつれて、そしてより多くのコンテナランタイムとの互換性を確保するために、Docker関連ロジックは分離され、Dockershimとして統合されました。

そのため、Kubernetes や Docker に変更を加える際には、適切なサポートを確保するために dockershim のメンテナンスが必要になります。しかし、dockershim を介して Docker を操作するには、本質的に Docker の基盤となるランタイムである Containerd を操作する必要があります。Containerd 自体は CRI (Container Runtime Interface) をサポートしているので、なぜ Docker の別のレイヤーを経由する必要があるのでしょうか?CRI を介して Containerd と直接やり取りすることはできないのでしょうか?これが、コミュニティが dockershim を立ち上げようとした理由の一つです。

では、コンテナ化とは何でしょうか?

ContainerdはDockerから派生したプロジェクトで、Kubernetes用のコンテナランタイムを提供することを目的として設計されており、イメージとコンテナのライフサイクル管理を担います。しかし、ContainerdはDockerとは独立して動作することも可能です。その機能は以下のとおりです。

  • OCI イメージ仕様 (runc とも呼ばれる) をサポートします。
  • OCIランタイム仕様をサポート
  • ミラープルをサポート
  • コンテナネットワーク管理をサポート
  • ストレージはマルチテナントをサポート
  • コンテナランタイムとコンテナライフサイクル管理をサポート
  • ネットワーク名前空間の管理をサポート

コマンドの使用法に関して、Containerd と Docker の主な違いは次のとおりです。

ご覧のとおり、使用方法はほぼ同じです。

以下では、kubeadm を使用して K8S クラスターをインストールし、コンテナ ランタイムとして containerd を使用する具体的なインストール手順について説明します。

環境の説明

ホストノード

ソフトウェアの説明

ソフトウェアバージョン

環境整備

(1)各ノードにホスト情報を追加します。

/etc/hosts を cat する

  1. 192.168.0.5 k8s-マスター
  2. 192.168.0.125 k8s-node01

(2)ファイアウォールを無効にする:

  1. $ systemctl 停止 ファイアウォール
  2. $ systemctl ファイアウォールを無効にする

(3)SELINUXを無効にする:

  1. $ setenforce 0
  2. /etc/selinux/config を cat する
  3. SELINUX=無効

(4)/etc/sysctl.d/k8s.confファイルを作成し、以下の内容を追加します。

  1. net.bridge.bridge-nf-call-ip6tables = 1
  2. net.bridge.bridge-nf-call-iptables = 1
  3. net.ipv4.ip_forward = 1

(5)変更を有効にするには、次のコマンドを実行します。

  1. $ modprobe br_netfilter
  2. $ sysctl -p /etc/sysctl.d/k8s.conf

(6)IPVSをインストールする

  1. $ cat > /etc/sysconfig/modules/ipvs.modules <<EOF
  2. #!/bin/bash
  3. modprobe -- ip_vs  
  4. modprobe -- ip_vs_rr  
  5. modprobe -- ip_vs_wrr  
  6. modprobe -- ip_vs_sh  
  7. modprobe -- nf_conntrack_ipv4  
  8. 終了
  9. $ chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

上記のスクリプトは `/etc/sysconfig/modules/ipvs.modules` ファイルを作成し、ノードの再起動後に必要なモジュールが自動的にロードされるようにします。`lsmod | grep -e ip_vs -e nf_conntrack_ipv4` コマンドを使用して、必要なカーネルモジュールが正しくロードされているかどうかを確認してください。

(7)ipsetパッケージがインストールされます。

  1. $ yum インストール ipset -y

IPVS のプロキシ ルールを簡単に表示するには、管理ツール ipvsadm をインストールするのが最適です。

  1. $ yum インストール ipvsadm -y

(8)サーバーの時間を同期する

  1. $ yum インストール chrony -y
  2. $ systemctl chronyd を有効にする
  3. $ systemctl chronyd を起動します
  4. $ chronyc ソース

(9)スワップパーティションを無効にする:

  1. $ スワップオフ -a

(10) /etc/fstab ファイルを編集し、SWAP の自動マウントをコメントアウトし、free -m コマンドでスワップが無効になっていることを確認します。/etc/sysctl.d/k8s.conf を編集し、以下の行を追加して swappiness パラメータを調整します。

  1. vm.swappiness=0

変更を適用するには、`sysctl -p /etc/sysctl.d/k8s.conf` を実行します。

(11)次にContainerdをインストールします。

  1. $ yum インストール -y yum-utils \
  2. デバイスマッパーの永続データ \
  3. lvm2
  4. $ yum-config-manager \
  5. --add-repo \  
  6. https://download.docker.com/linux/centos/docker-ce.repo
  7. `$ yum list | grep containerd`

バージョンをインストールすることを選択できます。たとえば、ここでは最新バージョンをインストールします。

  1. $ yum インストール containerd.io-1.4.4 -y

(12)containerd設定ファイルを作成する。

  1. mkdir -p /etc/containerd
  2. containerd 設定のデフォルト> /etc/containerd/config.toml
  3. # 設定ファイルを置き換える
  4. sed -i "s#k8s.gcr.io#registry.cn-hangzhou.aliyuncs.com/google_containers#g" /etc/containerd/config.toml
  5. sed -i '/containerd.runtimes.runc.options/a\ \ \ \ \ \ \ \ \ \ \ \ SystemdCgroup = true' /etc/containerd/config.toml
  6. sed -i "s#https://registry-1.docker.io#https://registry.cn-hangzhou.aliyuncs.com#g" /etc/containerd/config.toml

(13) Containerdを起動します。

  1. systemctlデーモンリロード
  2. systemctl コンテナを有効にする
  3. systemctl コンテナを再起動します

Containerdがインストールされ、上記の環境設定が完了したら、Kubeadmをインストールできます。ここでは、Alibaba Cloudのリポジトリを使用して、yumリポジトリを指定してインストールします。

  1. cat <<EOF > /etc/yum.repos.d/kubernetes.repo
  2. [Kubernetes]
  3. 名前=Kubernetes
  4. ベースURL=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
  5. 有効=1
  6. gpgcheck=0
  7. リポジトリgpgcheck=0
  8. gpgkey =http: //mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
  9. http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  10. 終了

次に、kubeadm、kubelet、kubectl をインストールします (最新バージョンをインストールしましたが、バージョン要件がある場合は、自分でバージョンを設定する必要があります)。

  1. $ yum install -y kubelet-1.20.5 kubeadm-1.20.5 kubectl-1.20.5

ランタイム設定:

  1. $ crictl config ランタイムエンドポイント /run/containerd/containerd.sock

ご覧のとおり、ここではバージョン v1.20.5 をインストールし、起動時に kubelet が自動的に起動するように設定しています。

  1. $ systemctl デーモンリロード
  2. $ systemctl kubelet を有効にする && systemctl kubelet を開始する

上記のすべての操作は、すべてのノードで構成する必要があります。

クラスタを初期化する

マスターを初期化する

次に、マスターノードでkubeadm初期化ファイルを設定します。デフォルトの初期化設定は、以下のコマンドでエクスポートできます。

  1. $ kubeadm config 印刷 init-defaults > kubeadm.yaml

次に、imageRepositoryの値を変更し、kube-proxyモードをipvsに設定するなど、必要に応じて設定を変更します。なお、ランタイムとしてcontainerdを使用しているため、ノードの初期化時にcgroupDriverをsystemdに指定する必要があることに注意してください[1]。

  1. APIバージョン: kubeadm.k8s.io/v1beta2
  2. ブートストラップトークン:
  3. - グループ:
  4. - システム:ブートストラップ:kubeadm:デフォルトの-node-token
  5. トークン: abcdef.0123456789abcdef
  6. ttl: 24h0m0s
  7. 使用法:
  8. - 署名
  9. - 認証
  10. 種類: InitConfiguration
  11. ローカルAPIエンドポイント:
  12. 広告アドレス: 192.168.0.5
  13. バインドポート: 6443
  14. ノード登録:
  15. criSocket: /run/containerd/containerd.sock
  16. 名前: k8s-master
  17. 汚染:
  18. - 効果: NoSchedule
  19. キー: node-role.kubernetes.io/master
  20. ---  
  21. apiサーバー:
  22. 制御プレーンのタイムアウト: 4分0秒
  23. APIバージョン: kubeadm.k8s.io/v1beta2
  24. 証明書ディレクトリ: /etc/kubernetes/pki
  25. クラスター名: kubernetes
  26. コントローラーマネージャー: {}
  27. DNS:
  28. タイプ: CoreDNS
  29. など:
  30. 地元
  31. データディレクトリ: /var/lib/etcd
  32. 画像リポジトリ: registry.cn-hangzhou.aliyuncs.com/google_containers
  33. 種類: ClusterConfiguration
  34. kubernetesバージョン: v1.20.5
  35. ネットワーキング:
  36. dnsドメイン: cluster.local  
  37. ポッドサブネット: 172.16.0.0/16
  38. サービスサブネット: 10.96.0.0/12
  39. スケジューラ: {}
  40. ---  
  41. apiバージョン: kubeproxy.config.k8s.io/v1alpha1
  42. 種類: KubeProxyConfiguration
  43. モード: ipvs
  44. ---  
  45. apiバージョン: kubelet.config.k8s.io/v1beta1
  46. 種類: KubeletConfiguration
  47. cgroupドライバー: systemd

次に、上記の設定ファイルを使用して初期化します。

  1. $ kubeadm init --config=kubeadm.yaml  
  2.  
  3. [init] Kubernetesバージョンv1.20.5を使用
  4. [プリフライト] プリフライトチェックの実行
  5. [事前準備] Kubernetes クラスターのセットアップ必要なイメージのプル
  6. [プリフライト] 1ほどかかる場合があります インターネット接続速度応じて、 1~ 2分 
  7. [プリフライト] この操作も実行できます 事前「kubeadm config images pull」を使用して 
  8. [certs] certificateDir フォルダ"/etc/kubernetes/pki"を使用します 
  9. [certs] 「ca」証明書を生成し   
  10. [certs] 「apiserver」証明書を生成し   
  11. [certs] apiserver サービング証明書DNS 名 [k8s-master kubernetes kubernetes. default kubernetes. default .svc kubernetes. default .svc.cluster. local ]およびIP [10.96.0.1 192.168.0.5]に対して署名されています
  12. [certs] 「apiserver-kubelet-client」証明書を生成し   
  13. [certs] 「front-proxy-ca」証明書を生成し   
  14. [certs] 「front-proxy-client」証明書を生成し   
  15. [certs] 「etcd/ca」証明書を生成し   
  16. [certs] 「etcd/server」証明書を生成し   
  17. [certs] etcd/server serving certDNS 名 [k8s-master localhost]IP アドレス [192.168.0.5 127.0.0.1 ::1]に対して署名されています
  18. [certs] 「etcd/peer」証明書を生成し   
  19. [certs] etcd/peer serving 証明書は、 DNS 名 [k8s-master localhost]IP アドレス [192.168.0.5 127.0.0.1 ::1]に対して署名されています
  20. [certs] 「etcd/healthcheck-client」証明書を生成し   
  21. [certs] 「apiserver-etcd-client」証明書を生成し   
  22. [certs] 「sa」を生成しています  そして 公共  
  23. [kubeconfig] kubeconfigフォルダ「/etc/kubernetes」を使用する 
  24. [kubeconfig] 「admin.conf」 kubeconfigファイルを書き込んでいます
  25. [kubeconfig] 「kubelet.conf」 kubeconfigファイルの書き込み
  26. [kubeconfig] 「controller-manager.conf」 kubeconfigファイルの書き込み
  27. [kubeconfig] 「scheduler.conf」 kubeconfigファイルの書き込み
  28. [kubelet-start]フラグ付きのkubelet 環境ファイルをファイル"/var/lib/kubelet/kubeadm-flags.env"書き込みます 
  29. [kubelet-start] kubelet設定をファイル「/var/lib/kubelet/config.yaml」書き込みます 
  30. [kubelet-start] kubeletの起動
  31. [コントロールプレーン] マニフェストフォルダ「/etc/kubernetes/manifests」を使用しています 
  32. [コントロールプレーン]静的ポッドマニフェストを作成しています  「kube-apiserver」  
  33. [コントロールプレーン]静的ポッドマニフェストを作成しています  「kube-コントローラー-マネージャー」  
  34. [コントロールプレーン]静的ポッドマニフェストを作成しています  「kube-scheduler」  
  35. [etcd]静的Podマニフェスト作成 ローカルetcd   /etc/kubernetes/マニフェスト 
  36. [wait-control-plane] kubeletコントロールプレーンを起動するのを待っています ディレクトリ「/etc/kubernetes/manifests」からの静的Pod 。これには最大4分かかる場合があります。
  37. [kubelet- check ] 初期タイムアウト40 秒が経過しました。
  38. [apiclient] 70.001862秒後、すべてのコントロールプレーンコンポーネントは正常です
  39. [upload-config] ConfigMap 「kubeadm-config」使用される設定を保存します  「kube-system」名前空間
  40. [kubelet] ConfigMap 「kubelet-config-1.20」の作成 クラスター内のkubelet設定を含む名前空間kube-system
  41. [upload-certs] フェーズをスキップします。-- upload-certsを参照してください。  
  42. [mark-control-plane]ラベル「node-role.kubernetes.io/master=''」を追加して、ノード k8s-master をコントロール プレーンとしてマークします。  そして  「node-role.kubernetes.io/control-plane='' (非推奨)」  
  43. [mark-control-plane] taint を追加しノード k8s-master をコントロールプレーンとしてマークします [node-role.kubernetes.io/master:NoSchedule]
  44. [bootstrap-token] 使用トークン: abcdef.0123456789abcdef
  45. [bootstrap-token] ブートストラップトークン、cluster-info ConfigMap、RBAC ロールの設定
  46. [bootstrap-token] RBACルールを設定して、 Node Bootstrapトークンがノードを取得できるようにしました。
  47. [bootstrap-token] RBACルールを設定して、 Node BootstrapトークンがCSRを投稿できるようしました  注文 ノードが長期証明書の資格情報を取得するため
  48. [bootstrap-token] は、csrapprover コントローラがノード ブートストラップ トークンからのCSR を自動的に承認できるようにRBAC ルールを構成しました。
  49. [bootstrap-token] RBACルールを設定して証明書のローテーションを許可しまし クラスター内のすべてのノードクライアント証明書
  50. [bootstrap-token] 「kube-public」名前空間 cluster-info」 ConfigMapを作成する
  51. [kubelet-finalize] 「/etc/kubernetes/kubelet.conf」を更新しています ローテーション可能なkubeletクライアント証明指し示し   
  52. [アドオン] 必須アドオンを適用: CoreDNS
  53. [アドオン] 必須アドオンを適用しました: kube-proxy
  54.  
  55. Kubernetes コントロールプレーンが正常に初期化されました。
  56.  
  57. クラスターの使用を開始するには通常のユーザーとして次のコマンドを実行する必要があります
  58.  
  59. mkdir -p $HOME/.kube
  60. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  61. sudo chown $(id -u):$(id -g) $HOME/.kube/config
  62.  
  63. あるいは、 rootユーザーの場合は、次のコマンドを実行できます。
  64.  
  65. KUBECONFIG=/etc/kubernetes/admin.conf をエクスポートします。
  66.  
  67. ここで、クラスターポッド ネットワークをデプロイする必要があります。
  68. 「kubectl apply -f [podnetwork].yaml」を実行します。  以下にリストされているオプションいずれかを使用します
  69. https://kubernetes.io/docs/concepts/cluster-administration/addons/
  70.  
  71. 参加できます 任意のワーカーノードで、ワーカーノード次のコマンドをrootとして実行します
  72.  
  73. kubeadm参加192.168.0.5:6443 --token abcdef.0123456789abcdef \  
  74. --discovery-token-ca-cert-hash sha256:446623b965cdb0289c687e74af53f9e9c2063e854a42ee36be9aa249d3f0ccec  

kubeconfigファイルをコピーする

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

ノードを追加

事前にクラスタの初期化設定と操作を完了しておいてください。マスターノードの `$HOME/.kube/config` ファイルを、ノードの対応するファイルにコピーします。kubeadm、kubelet、kubectl をインストールします。初期化が完了したら、プロンプトが表示されるので `join` コマンドを実行します。

  1. # kubeadm join 192.168.0.5:6443 --token abcdef.0123456789abcdef \  
  2. > --discovery-token-ca-cert-hash sha256:446623b965cdb0289c687e74af53f9e9c2063e854a42ee36be9aa249d3f0ccec  
  3. [プリフライト] プリフライトチェックの実行
  4. [プリフライト]クラスターから構成を読み取っています...
  5. [プリフライト] 参考までに:この設定ファイルはのように確認できます。   'kubectl -n kube-system get cm kubeadm-config -o yaml'  
  6. [kubelet-start] kubelet設定をファイル「/var/lib/kubelet/config.yaml」書き込みます 
  7. [kubelet-start]フラグ付きのkubelet 環境ファイルをファイル"/var/lib/kubelet/kubeadm-flags.env"書き込みます 
  8. [kubelet-start] kubeletの起動
  9. [kubelet-start] kubelet がTLS ブートストラップを実行するのを待機しています...
  10.  
  11. このノードはクラスターに参加しました:
  12. * 証明書署名要求がapiserver送信され応答が受信されました。
  13. * Kubelet に新しい安全な接続の詳細通知されました
  14.  
  15. 「kubectl get nodes」を実行します コントロールプレーンこのノードがクラスターに参加すること確認します。

上記の join コマンドを忘れた場合は、コマンド `kubeadm token create --print-join-command` を使用して再度取得できます。

実行が成功したら、`get nodes` コマンドを実行します。

  1. $ kubectl 取得番号 
  2. 名前ステータス 役割 年齢 バージョン
  3. k8s-master NotReady コントロールプレーン、マスター 29m v1.20.5
  4. k8s-node01 準備完了なし <なし> 28分 v1.20.5

ご覧の通り、ネットワークプラグインがまだインストールされていないため、NotReady状態になっています。次に、ネットワークプラグインをインストールします。ドキュメント(https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/)で、ご自身のネットワークプラグインを選択できます。ここでは、Calioをインストールします。

  1. $ wget https://docs.projectcalico.org/v3.8/manifests/calico.yaml

# 一部のノードには複数のネットワーク インターフェイスがあるため、リソース マニフェスト ファイルで内部ネットワーク インターフェイスを指定する必要があります。

$ vi calico.yaml

  1. ……
  2. 仕様:
  3. コンテナ:
  4. - 環境:
  5. -名前: DATASTORE_TYPE
  6. 値: Kubernetes
  7. - name : IP_AUTODETECTION_METHOD # この環境変数をDaemonSetに追加します
  8. 値: interface=eth0 # 内部ネットワークインターフェースカードを指定します
  9. -名前: WAIT_FOR_DATASTORE
  10. 値: "true"  
  11. - name : CALICO_IPV4POOL_CIDR # 172 ネットワーク セグメントは init 中に設定されたため、これを変更する必要があります。
  12. 値: "172.16.0.0/16"  
  13.  
  14. ……

calico ネットワーク プラグインをインストールします。

  1. $ kubectl apply -f calico.yaml

時々、Pod の実行ステータスを確認します。

  1. # kubectl get ポッド -n kube-system
  2. 名前準備完了 ステータス 再起動 年齢
  3. calico-kube-controllers-bcc6f659f-zmw8n 0/1 コンテナ作成 0 7分58秒
  4. calico-node-c4vv7 1/1 実行中 0 7分58秒
  5. calico-node-dtw7g 0/1 ポッド初期化中 0 7分58秒
  6. coredns-54d67798b7-mrj2b 1/1 実行中 0 46分
  7. coredns-54d67798b7-p667d 1/1 実行中 0 46分
  8. etcd-k8s-master 1/1 実行中 0 46分
  9. kube-apiserver-k8s-master 1/1 実行中 0 46分
  10. kube-controller-manager-k8s-master 1/1 実行中 0 46分
  11. kube-proxy-clf4s 1/1 実行中 0 45分
  12. kube-proxy-mt7tt 1/1 実行中 0 46分
  13. kube-scheduler-k8s-master 1/1 実行中 0 46分

ネットワーク プラグインは正常に実行されており、ノードのステータスは正常です。

  1. # kubectl ノードを取得する
  2. 名前ステータス 役割 年齢 バージョン
  3. k8s-master コントロールプレーン、マスター 47m v1.20.5 が準備完了
  4. k8s-node01 準備完了 <なし> 46m v1.20.5

同じ方法を使用して別のノードを追加することもできます。

コマンドの自動補完を設定する

  1. yum install -y bash補完
  2. ソース /usr/share/bash-completion/bash_completion
  3. ソース <(kubectl 補完 bash)
  4. echo "source <(kubectl 補完 bash)" >> ~/.bashrc

参考資料

【1】:https://github.com/containerd/containerd/issues/4857

【2】:https://github.com/containerd/containerd