Observability とOracle Cloud について考える
この記事は、 JPOUG Advent Calendar 2021 14日目の記事です。
13日目は wmo6hashさんの記事『「働き方の新しいスタイル」への仕事場の最適化』でした。
本記事ではObservabilityというものについて考え、Oracle Cloudでどう実現したら良いのか考えてみます。
Observabilityとは何か
まずは歴史的経緯を見てみましょう。こちらのサイトがとてもよくまとまっていました。
そのサイトによると
- 1960年に電気工学の制御理論の中で「Observability」という考えが出てきた
- 2013年にObservability at Twitterという記事でITシステムにObservabilityという言葉が使われた
- 2017年にMetrics, tracing, and loggingの3つの柱の重要性が解かれた
- 2019年に3つの柱を見直す動きがあり(特にログはマイクロサービスではデータ量が肥大化する)、活発な議論が今でもされている
という事がわかりました。3つの柱が重要なのは事実ですが、扱い方にフォーカスが移っているようです。
システムの内部状態を理解でき、探索できるようにし、何が起きたのかという疑問に答えられるようにすること。それがObservabilityだと結んでいます。
記事中で私が最も興味を持ったのが以下のツイートです。
✨THERE ARE NO✨
— Charity Majors (@mipsytipsy) 2018年9月25日
✨THREE PILLARS OF✨
✨OBSERVABILITY.✨
and the fact that everybody keeps blindly repeating this mantra (and cargo culting these primitives) is probably why our observability tooling is 10 years behind the rest of our software tool chain. https://t.co/94yDBPuDRv
Charity Majorsさんは一連のツイートの中で、イベント を中心に考えないと3つの柱は意味がないと言っています。盲目的に3つの柱を推奨するのはやめましょうと。
ログ、メトリクス、トレースはイベントから生まれるもので、ログやメトリクスをいくら集めてもイベントにはならない。ツールありきだと何種類ものツールを行ったり来たりすることになると(強めの口調で)言われています。
Charity Majorsさんはhoneycomb.ioと言う会社のCTOで、コーポレートサイトのブログは、参考になる記事が多いです。
その中でFramework for an Observability Maturity Modelという記事があるので紹介します。
これは組織のObiservability成熟度レベルに関する記事です。
ざっくり紹介しますけど、本文にはチェックリストもあるのでぜひ読んでみてください。
Framework for an Observability Maturity Model
- Observabilityのゴール
- サステナブルなシステムとエンジニアの幸福
- 観測可能なシステムは所有と維持が容易で、エンジニアが楽になる
- エンジニアの幸福度が上がれば離職率も下がり、新規採用コストを下げる事ができる
- ビジネスニーズの充足と顧客の幸福
- Observabilityはビジネスを成功させるためのもの
- 可視性の高いシステムがあれば顧客に必要なものを理解でき、効率よく安全に提供できるようになる
- 観測性は、コンピュータシステムだけの特性でもなければ、人間だけの特性でもない。
- Observabilityに関する議論は、装置、ストレージ、クエリなどの技術的な部分にのみ焦点が当てられ、システムが実際にどのように使用されているかについては議論されないことが多い。
- チームが問題解決のためにツールを使用することに違和感を感じたり、不安を感じたりすると、結果を出すことができない。ツールの品質は、機能の追加が容易かどうか、十分な粒度でデータを取り込むことができるかどうか、人間が発する質問に答えられるかどうか、などの要素によって決まる。
- サステナブルなシステムとエンジニアの幸福
- Observabilityの品質が影響をもたらすもの
- システム障害に対して、回復性(resilience)を持たせる
- Observabilityの質を上げると
- チーム内にスキルが分散しているので、全員が障害に対応できる
- 対応不要な偽アラートがなく、ストレスが少ない
- トレーサビリティの高い監視で問題を迅速に解決できる
- Observabilityの質を上げると
- 高品質なコードをデリバリ
- Observabilityの質を上げると
- どこでエラーになったのか容易に確認できる
- 豊富なテレメトリを提供することでエンジニアはユーザの目に触れる前に修復できる
- Observabilityの質を上げると
- 複雑性と技術的負債の管理
- Observabilityの質を上げると
- 障害や遅延の原因を素早く発見できるようになる
- 勘や推測ではなく最適化すべきコードを特定できる
- Observabilityの質を上げると
- 流れを予測できるリリース
- Observabilityの質を上げると
- ビルドやデプロイの問題に早く気づける
- 新旧のビルドIDを比較することで、コードの変化が意図したものかどうか確認できる
- Observabilityの質を上げると
- ユーザの振る舞いを知る
- Observabilityの質を上げると
- イベントドリブンなデータ分析と予測可能なリリースサイクルを構築できる
- プロダクトマネージャは自分たちの変更がどれだけビジネス目標を達成したか理解し、反復して機能開発できる
- Observabilityの質を上げると
- システム障害に対して、回復性(resilience)を持たせる
Observabilityって結局なんなの?
今も議論されているので明確な定義はないのでしょうが、私個人の見解としては、『仕組みと組織が、「何が起きたのか」というシステムへの問いかけに対してどのくらい答えられるか』ですかね?
ログを集約させたけど誰もみてないとか、無視していいアラートが多いとかっていうケースは割とよくある気がしてて、目的をしっかり持ってツールを入れないとダメだと思ってます。
昔、社内研修用にObservabilityとか監視に関する以下の資料を作った事があるんですが、当時とあまり考えは変わってないのかなという気もしてます。
現在、私の職場ではDatadogを使っています。非常に高機能な製品で文句の付け所がありません。
が、我々の使い方はモニタリングツールとして使っている比率が高くて、障害発生時の調査や分析という使い方が十分出来ているとは思っていません。
だからといって無闇矢鱈とDatadogに集約させると言うよりかは、課題をしっかりと定義して解決策の1つとして使っていけたら良いのかなと思ってます。
Oracle Cloud におけるObservability
Oracle Cloud にはOracle Cloud Observability and Management Platformというものがあります。
プレスリリースや紹介記事を見てると
などの特徴があるようです。Javaアプリケーションであればトレース・エクスプローラ で、前述したようなイベントベースの分析が可能になるように思います。
またはResource Managerを使うことで、インフラレイヤのデリバリを高速化出来るかもしれません。
いくら便利なツールがあってもツールはあくまでも組織の加速装置だし、アラートに対して対応するかどうかは最終的には人間が判断する事です。
皆さんも何が課題で、どうやってその課題を解決するのか検討してObservabilityを育てていきましょう。
お読みいただきありがとうございました。
Kubernetes The Hard Way On VirtualBox 9日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの9日目。
今日はリモートアクセス用のkubectlの設定です。
Configuring kubectl for Remote Access
今回は admin
ユーザの証明書を元に、kubectl
コマンドのためのkubeconfigファイルを作成します。
The Admin Kubernetes Configuration File
kubeconfgには、接続するKUbernetesAPIServerが必要です。高可用性をサポートするために、外部ロードバランサのIPアドレスを使用します。
{ KUBERNETES_LB_ADDRESS=192.168.5.30 kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.crt \ --embed-certs=true \ --server=https://${KUBERNETES_LB_ADDRESS}:6443 kubectl config set-credentials admin \ --client-certificate=admin.crt \ --client-key=admin.key kubectl config set-context kubernetes-the-hard-way \ --cluster=kubernetes-the-hard-way \ --user=admin kubectl config use-context kubernetes-the-hard-way }
Verification
接続して確認
kubectl get componentstatuses
以下のように出力されればOK
vagrant@master-1:~$ kubectl get componentstatusesWarning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR scheduler Healthy ok etcd-0 Healthy {"health":"true","reason":""} etcd-1 Healthy {"health":"true","reason":""} controller-manager Healthy ok
最後までお読み頂き有難うございました。
Kubernetes The Hard Way On VirtualBox 8日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの8日目。
今日はKubernetes のWorker NodeのTLS Bootstrapping。だいぶ来てますね。
更新がやたら遅いのは忙しいわけでも体調が悪いわけでもなく、怠惰です。
7つの大罪を順調に犯してます。
TLS Bootstrapping Worker Nodes
前回までは以下のことを行ってきました
- ワーカーノード用の鍵ペアのセットを自分で作成する
- 自分でCAに署名してもらう
- この証明書を使用したkube-configファイルを自分で作成する
- 証明書の有効期限が切れるたびに、同じ手順で証明書を更新しなければならない
これは数千のノードがあり、動的に追加削除されるような環境を運用する場合には実用的ではありません
TLS boostrapping を使うことで
- ノードは鍵ペアを自分で作成できる
- ノードはCSRを作成できる
- ノードはAPIを使ってCSRをKubernetesCAに送信できる
- ノードはKubernetesCAの署名付き証明書を取得できる
- ノードはその証明書を使った kube-config ファイルを自分で作成できる
- ノードはクラスタの起動や参加を自分で出来る
- ノードは新しい証明書のCSRを作成できるが、クラスタの管理者が手動で承認する必要がある
Kubernetes 1.11では、セキュリティ上の理由から、ノードがCSRを発行する際に管理者またはコントローラの承認を必要とするパッチがマージされました。
What is required for TLS Bootstrapping
証明書APIは(先程説明したように)、証明書の管理(CSRの作成、CAによって署名された証明書の取得、署名された証明書の取得など)に役立つAPIのセットをKubernetes上で提供します。ワーカーノード(kubelets)は、このAPIを使用してKubernetes CAによって署名された証明書を取得する機能を持っています。
Pre-Requisite
kube-apiserver
kube-apiserver の /etc/systemd/system/kube-apiserver.service
で、以下の設定がされているか確認しましょう。
bootstrap token認証が有効になっているかの設定です。
--enable-bootstrap-token-auth=true
kube-controller-manager
証明書要求は、最終的にkube-controller-managerによって署名されます。
kube-controller-managerは、これらの操作を実行するためにCA証明書とキーを必要とします。
kube-controller-manager.service
で、以下の設定が有効になっているか確認します。
--cluster-signing-cert-file=/var/lib/kubernetes/ca.crt \\ --cluster-signing-key-file=/var/lib/kubernetes/ca.key
master-1 の証明書をworker-2もコピーします
vagrant@master-1:~$ scp ./ca.crt 192.168.5.22:/home/vagrant/ ca.crt 100% 1001 2.8MB/s 00:00
Configure the Binaries on the Worker node
この作業はworker-2で行います。
ワーカのバイナリをダンロードしてインストールします。
worker-2$ wget -q --show-progress --https-only --timestamping \ https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kubectl \ https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-proxy \ https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kubelet
インストール用のディレクトリ作成
worker-2$ sudo mkdir -p \ /etc/cni/net.d \ /opt/cni/bin \ /var/lib/kubelet \ /var/lib/kube-proxy \ /var/lib/kubernetes \ /var/run/kubernetes
バイナリをインストール
{ chmod +x kubectl kube-proxy kubelet sudo mv kubectl kube-proxy kubelet /usr/local/bin/ }
証明書を移動
worker-2$ sudo mv ca.crt /var/lib/kubernetes/
Step 1 Create the Boostrap Token to be used by Nodes(Kubelets) to invoke Certificate API
証明書APIにアクセスするworkerノード(kubelet)にとって、まず kubernetes api-server への認証が必要です。ここではkubeletが使う Bootstrap Tokens を作成します。
Bootstrap Tokens は、6文字のトークンIDと、ドットで区切られた16文字のトークン・シークレットで構成されています。(例:abcdef.0123456789abcdef.)
master-1
で行います。
$ cat > bootstrap-token-07401b.yaml <<EOF apiVersion: v1 kind: Secret metadata: # Name MUST be of form "bootstrap-token-<token id>" name: bootstrap-token-07401b namespace: kube-system # Type MUST be 'bootstrap.kubernetes.io/token' type: bootstrap.kubernetes.io/token stringData: # Human readable description. Optional. description: "The default bootstrap token generated by 'kubeadm init'." # Token ID and secret. Required. token-id: 07401b token-secret: f395accd246ae52d # Expiration. Optional. expiration: 2031-03-10T03:22:11Z # Allowed usages. usage-bootstrap-authentication: "true" usage-bootstrap-signing: "true" # Extra groups to authenticate the token as. Must start with "system:bootstrappers:" auth-extra-groups: system:bootstrappers:worker EOF
作成時の注意として
expiration
が未来の日付になっていることauth-extra-groups
が "system:bootstrappers:" で始まる必要があること。このグループは今は存在していないけど、ワーカーノードが所属するグループ。このグループは、このトークンに関連付けられています。
kubectlコマンドで作成します。
master-1$ kubectl create -f bootstrap-token-07401b.yaml
Step 2 Authorize workers(kubelets) to create CSR
次に、先ほど作成したグループをsystem:node-bootstrapper
ClusterRoleに紐づけます。このClusterRoleはグループに、kubeletを起動するのに十分な権限を与えます。
まずはCSRを作成します。
master-1
で行います。
$ kubectl create clusterrolebinding create-csrs-for-bootstrapping --clusterrole=system:node-bootstrapper --group=system:bootstrappers
Step 3 Authorize workers(kubelets) to approve CSR
先程作ったCSRを承認します。
master-1
で行います。
$ kubectl create clusterrolebinding auto-approve-csrs-for-group --clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient --group=system:bootstrappers
Step 3 Authorize workers(kubelets) to Auto Renew Certificates on expiration
次は、Cluster Role Binding
を作成します。これは証明書の期限を自動的に更新するのにノードに必要なものです。
注意として、system:bootstrappers
グループは使いません。なぜなら更新期間までにはノードは起動していて既にクラスタの一部になっているからです。
全てのノードは system:nodes
グループです。
master-1
で行います。
$ kubectl create clusterrolebinding auto-approve-renewals-for-nodes --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient --group=system:nodes
Step 4 Configure Kubelet to TLS Bootstrap
ここでは2つ目のワーカーノードに作成したtokrnを使ってTLS bootstrapの設定をします。
worker-1
では、手動で作成したTLS証明書を使ってkubeconfigを作成するところから始めました。
しかしここでは、まだ証明書を持っていませんのでkubecobfigを作成できません。
代わりに、作成したtokenの情報をもとにbootstrap-kubeconfig
を作成します。
これはworker-2
で行います。
sudo kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-cluster bootstrap --server='https://192.168.5.30:6443' --certificate-authority=/var/lib/kubernetes/ca.crt sudo kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-credentials kubelet-bootstrap --token=07401b.f395accd246ae52d sudo kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig set-context bootstrap --user=kubelet-bootstrap --cluster=bootstrap sudo kubectl config --kubeconfig=/var/lib/kubelet/bootstrap-kubeconfig use-context bootstrap
Step 5 Create Kubelet Config File
kubelet-config.yaml
を作成します。
これはworker-2
で行います。
$ cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: "/var/lib/kubernetes/ca.crt" authorization: mode: Webhook clusterDomain: "cluster.local" clusterDNS: - "10.96.0.10" resolvConf: "/run/systemd/resolve/resolv.conf" runtimeRequestTimeout: "15m" EOF
Step 6 Configure Kubelet Service
kubelet.service
というsystemdのunitファイルを作成します。
これはworker-2
で行います。
$ cat <<EOF | sudo tee /etc/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet Documentation=https://github.com/kubernetes/kubernetes After=docker.service Requires=docker.service [Service] ExecStart=/usr/local/bin/kubelet \\ --bootstrap-kubeconfig="/var/lib/kubelet/bootstrap-kubeconfig" \\ --config=/var/lib/kubelet/kubelet-config.yaml \\ --image-pull-progress-deadline=2m \\ --kubeconfig=/var/lib/kubelet/kubeconfig \\ --cert-dir=/var/lib/kubelet/pki/ \\ --rotate-certificates=true \\ --network-plugin=cni \\ --register-node=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Step 7 Configure the Kubernetes Proxy
以前作成したkube-proxy.kubeconfig
ファイルを移動します。
これはworker-2
で行います。
$ sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
kube-proxy-config.yaml
ファイルを作成します。
$ cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 clientConnection: kubeconfig: "/var/lib/kube-proxy/kubeconfig" mode: "iptables" clusterCIDR: "192.168.5.0/24" EOF
kube-proxy.service
というsystemdのunitファイルを作成します。
$ cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service [Unit] Description=Kubernetes Kube Proxy Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-proxy \\ --config=/var/lib/kube-proxy/kube-proxy-config.yaml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Step 8 Start the Worker Services
サービスを起動します。
これはworker-2
で行います。
{ sudo systemctl daemon-reload sudo systemctl enable kubelet kube-proxy sudo systemctl start kubelet kube-proxy }
Step 9 Approve Server CSR
master-1
でCSRを確認します。
vagrant@master-1:~$ kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION csr-bf8xb 40s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:07401b <none> Approved,Issued
承認します。(CONDITIONが既にApproved
になってるような。。。)
$ kubectl certificate approve csr-bf8xb
Verification
master-1
で登録されたnodeの確認をします。
vagrant@master-1:~$ kubectl get nodes --kubeconfig admin.kubeconfig NAME STATUS ROLES AGE VERSION worker-1 NotReady <none> 35d v1.22.0 worker-2 NotReady <none> 3m56s v1.22.0
ネットワークの設定が終わってないのでNotReady
で大丈夫です。
最後までお読み頂き有難うございました!
さすがにペースを上げよう。。。
Kubernetes The Hard Way On VirtualBox 7日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの7日目。
今日はKubernetes のWorker Nodeを作成します。だいぶ来てますね。
Bootstrapping the Kubernetes Worker Nodes
今回はDockerがすでにインストールされたworkerノードにセットアップをしていきます。
以下のコンポーネントをインストールします。
- kubelet
- kube-proxy
Prerequisites
証明書や設定は master-1
ノードで作成し、 scp
を使ってworkerノードに転送します。
それが終わるとworker-1
でコマンドを実行します。worker-1
にはSSHターミナルを使ってログインします。
Provisioning Kubelet Client Certificates
Kubernetesは Node Authorizer
と呼ばれる認証モードを使います。これはKubeletsからのAPIリクエストを認証します。
Node Authorizer
に認証されるために、Kubeletsはsystem:node:<nodeName>
のユーザ名でsystem:nodes
グループにあることを識別する資格情報を使用する必要があります。
このセクションでは、Node Authorizer
の要件を満たす証明書を、Kubernetesワーカーノードごとに作成します。
1つのworkerノード用に証明書と秘密鍵を作成します。
master-1
で実行します。
cat > openssl-worker-1.cnf <<EOF [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = worker-1 IP.1 = 192.168.5.21 EOF
openssl genrsa -out worker-1.key 2048 openssl req -new -key worker-1.key -subj "/CN=system:node:worker-1/O=system:nodes" -out worker-1.csr -config openssl-worker-1.cnf openssl x509 -req -in worker-1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out worker-1.crt -extensions v3_req -extfile openssl-worker-1.cnf -days 1000
以下のファイルが作成されます。
worker-1.key worker-1.crt
The kubelet Kubernetes Configuration File
Kubelets用のkubeconfigファイルを生成する際には、Kubeletsのノード名に一致するクライアント証明書を使用する必要があります。
これにより、Kubernetes Node AuthorizerによってKubeletsが適切に認証されるようになります。
kub-api server load-balancer IP を設定
LOADBALANCER_ADDRESS=192.168.5.30
最初のワーカーノード用の kubeconfig ファイルを作成します。
master-1
で行います。
{ kubectl config set-cluster kubernetes-the-hard-way \ --certificate-authority=ca.crt \ --embed-certs=true \ --server=https://${LOADBALANCER_ADDRESS}:6443 \ --kubeconfig=worker-1.kubeconfig kubectl config set-credentials system:node:worker-1 \ --client-certificate=worker-1.crt \ --client-key=worker-1.key \ --embed-certs=true \ --kubeconfig=worker-1.kubeconfig kubectl config set-context default \ --cluster=kubernetes-the-hard-way \ --user=system:node:worker-1 \ --kubeconfig=worker-1.kubeconfig kubectl config use-context default --kubeconfig=worker-1.kubeconfig }
以下のファイルが作成されます
worker-1.kubeconfig
Copy certificates, private keys and kubeconfig files to the worker node:
master-1
で行います。
scp ca.crt worker-1.crt worker-1.key worker-1.kubeconfig worker-1:~/
Download and Install Worker Binaries
以下のコマンドは全て worker-1
ノードで行います
wget -q --show-progress --https-only --timestamping \ https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kubectl \ https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-proxy \ https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kubelet
インストール用のディレクトリ作成
sudo mkdir -p \ /etc/cni/net.d \ /opt/cni/bin \ /var/lib/kubelet \ /var/lib/kube-proxy \ /var/lib/kubernetes \ /var/run/kubernetes
落としたバイナリをインストールします
{ chmod +x kubectl kube-proxy kubelet sudo mv kubectl kube-proxy kubelet /usr/local/bin/ }
Configure the Kubelet
worker-1
ノードで行います
{ sudo mv ${HOSTNAME}.key ${HOSTNAME}.crt /var/lib/kubelet/ sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig sudo mv ca.crt /var/lib/kubernetes/ }
kubelet-config.yaml
を作成します。
cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: "/var/lib/kubernetes/ca.crt" authorization: mode: Webhook clusterDomain: "cluster.local" clusterDNS: - "10.96.0.10" resolvConf: "/run/systemd/resolve/resolv.conf" runtimeRequestTimeout: "15m" EOF
kubelet.service
というsystemd unit file を作成します
cat <<EOF | sudo tee /etc/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet Documentation=https://github.com/kubernetes/kubernetes After=docker.service Requires=docker.service [Service] ExecStart=/usr/local/bin/kubelet \\ --config=/var/lib/kubelet/kubelet-config.yaml \\ --image-pull-progress-deadline=2m \\ --kubeconfig=/var/lib/kubelet/kubeconfig \\ --tls-cert-file=/var/lib/kubelet/${HOSTNAME}.crt \\ --tls-private-key-file=/var/lib/kubelet/${HOSTNAME}.key \\ --network-plugin=cni \\ --register-node=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Configure the Kubernetes Proxy
worker-1
ノードで行います
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
kube-proxy-config.yaml
を作成します
cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 clientConnection: kubeconfig: "/var/lib/kube-proxy/kubeconfig" mode: "iptables" clusterCIDR: "192.168.5.0/24" EOF
kube-proxy.service
というsystemd unit file を作成します
cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service [Unit] Description=Kubernetes Kube Proxy Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-proxy \\ --config=/var/lib/kube-proxy/kube-proxy-config.yaml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Start the Worker Services
worker-1
ノードで行います
{ sudo systemctl daemon-reload sudo systemctl enable kubelet kube-proxy sudo systemctl start kubelet kube-proxy }
起動確認ヨシ!
agrant@worker-1:~$ sudo systemctl status kubelet ● kubelet.service - Kubernetes Kubelet Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2021-10-19 14:46:31 UTC; 7s ago Docs: https://github.com/kubernetes/kubernetes Main PID: 17678 (kubelet) Tasks: 10 (limit: 546) CGroup: /system.slice/kubelet.service └─17678 /usr/local/bin/kubelet --config=/var/lib/kubelet/kubelet-config.yaml --imag Oct 19 14:46:32 worker-1 kubelet[17678]: I1019 14:46:32.529456 17678 plugin_manager.go:112] Oct 19 14:46:32 worker-1 kubelet[17678]: I1019 14:46:32.529548 17678 plugin_manager.go:114] Oct 19 14:46:32 worker-1 kubelet[17678]: I1019 14:46:32.531274 17678 container_manager_linux Oct 19 14:46:32 worker-1 kubelet[17678]: E1019 14:46:32.531536 17678 eviction_manager.go:255 Oct 19 14:46:32 worker-1 kubelet[17678]: I1019 14:46:32.569573 17678 kubelet_node_status.go: Oct 19 14:46:33 worker-1 kubelet[17678]: I1019 14:46:33.142328 17678 apiserver.go:52] "Watch Oct 19 14:46:33 worker-1 kubelet[17678]: I1019 14:46:33.345623 17678 kubelet.go:2053] "SyncL Oct 19 14:46:33 worker-1 kubelet[17678]: I1019 14:46:33.419185 17678 reconciler.go:157] "Rec Oct 19 14:46:37 worker-1 kubelet[17678]: I1019 14:46:37.113377 17678 cni.go:239] "Unable to Oct 19 14:46:37 worker-1 kubelet[17678]: E1019 14:46:37.549652 17678 kubelet.go:2332] "Conta vagrant@worker-1:~$ sudo systemctl status kube-proxy ● kube-proxy.service - Kubernetes Kube Proxy Loaded: loaded (/etc/systemd/system/kube-proxy.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2021-10-19 14:46:31 UTC; 14s ago Docs: https://github.com/kubernetes/kubernetes Main PID: 17679 (kube-proxy) Tasks: 5 (limit: 546) CGroup: /system.slice/kube-proxy.service └─17679 /usr/local/bin/kube-proxy --config=/var/lib/kube-proxy/kube-proxy-config.ya Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.938378 17679 conntrack.go:83] Set Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.958640 17679 conntrack.go:100] Se Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.958971 17679 conntrack.go:100] Se Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.963801 17679 config.go:315] Start Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.964052 17679 shared_informer.go:2 Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.964153 17679 config.go:224] Start Oct 19 14:46:32 worker-1 kube-proxy[17679]: I1019 14:46:32.964241 17679 shared_informer.go:2 Oct 19 14:46:32 worker-1 kube-proxy[17679]: E1019 14:46:32.991244 17679 event_broadcaster.go Oct 19 14:46:33 worker-1 kube-proxy[17679]: I1019 14:46:33.064980 17679 shared_informer.go:2 Oct 19 14:46:33 worker-1 kube-proxy[17679]: I1019 14:46:33.065520 17679 shared_informer.go:2 vagrant@worker-1:~$
Verification
master-1
ノードで行います
登録されたKubernetesノードをマスターノードから確認
kubectl get nodes --kubeconfig admin.kubeconfig
以下のように出力されればおK
vagrant@master-1:~$ kubectl get nodes --kubeconfig admin.kubeconfig NAME STATUS ROLES AGE VERSION worker-1 NotReady <none> 78s v1.22.0
NotReady
なのはネットワーク設定を行っていないからだそうです・
今回はここまで!
お読みいただきありがとうございました!
Kubernetes The Hard Way On VirtualBox 6日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの6日目。
今回はKubernetes のControl Planeを作成します。
いよいよそれっぽくなってきました。
Bootstrapping the Kubernetes Control Plane
今回は高可用性のために2つのインスタンスにControl Planeを設定します。また、Kubernetes API Serverをリモートクライアントに公開するためのロードバランサも作成します。
以下のコンポーネントが2つのノードにインストールされます
- Kubernetes API Server
- Scheduler
- Controller Manager
Prerequisites
今回の作業は maste-1
master-2
両方に行います
Provision the Kubernetes Control Plane
設定用のディレクトリ作成
sudo mkdir -p /etc/kubernetes/config
Download and Install the Kubernetes Controller Binaries
公式のバイナリをダウンロードします。公式手順だと v1.13.0
なんですけど流石に古いので、執筆時点で最新の v1.22.0
に変えてます。
リリース情報は https://kubernetes.io/docs/setup/release/#server-binaries から確認できます。
wget -q --show-progress --https-only --timestamping \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-apiserver" \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-controller-manager" \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kube-scheduler" \ "https://storage.googleapis.com/kubernetes-release/release/v1.22.0/bin/linux/amd64/kubectl"
バイナリをインストールします。
{ chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/ }
Configure the Kubernetes API Server
証明書と暗号化に関するファイルを配置します。
{ sudo mkdir -p /var/lib/kubernetes/ sudo cp ca.crt ca.key kube-apiserver.crt kube-apiserver.key \ service-account.key service-account.crt \ etcd-server.key etcd-server.crt \ encryption-config.yaml /var/lib/kubernetes/ }
インスタンスの内部IPアドレスはAPIサーバをクラスターメンバにする際のアドバタイズに使われます。
現在の内部IPアドレスを取得しておきます。
INTERNAL_IP=$(ip addr show enp0s8 | grep "inet " | awk '{print $2}' | cut -d / -f 1)
確認します。
echo $INTERNAL_IP
kube-apiserver.service
という、systemdのunitファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-apiserver \\ --advertise-address=${INTERNAL_IP} \\ --allow-privileged=true \\ --apiserver-count=2 \\ --audit-log-maxage=30 \\ --audit-log-maxbackup=3 \\ --audit-log-maxsize=100 \\ --audit-log-path=/var/log/audit.log \\ --authorization-mode=Node,RBAC \\ --bind-address=0.0.0.0 \\ --client-ca-file=/var/lib/kubernetes/ca.crt \\ --enable-admission-plugins=NodeRestriction,ServiceAccount \\ --enable-swagger-ui=true \\ --enable-bootstrap-token-auth=true \\ --etcd-cafile=/var/lib/kubernetes/ca.crt \\ --etcd-certfile=/var/lib/kubernetes/etcd-server.crt \\ --etcd-keyfile=/var/lib/kubernetes/etcd-server.key \\ --etcd-servers=https://192.168.5.11:2379,https://192.168.5.12:2379 \\ --event-ttl=1h \\ --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\ --kubelet-certificate-authority=/var/lib/kubernetes/ca.crt \\ --kubelet-client-certificate=/var/lib/kubernetes/kube-apiserver.crt \\ --kubelet-client-key=/var/lib/kubernetes/kube-apiserver.key \\ --kubelet-https=true \\ --runtime-config=api/all=true \\ --service-account-key-file=/var/lib/kubernetes/service-account.crt \\ --service-cluster-ip-range=10.96.0.0/24 \\ --service-node-port-range=30000-32767 \\ --tls-cert-file=/var/lib/kubernetes/kube-apiserver.crt \\ --tls-private-key-file=/var/lib/kubernetes/kube-apiserver.key \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Configure the Kubernetes Controller Manager
kube-controller-manager のkubeconfigを配置します
sudo cp kube-controller-manager.kubeconfig /var/lib/kubernetes/
kube-controller-manager.service
という、systemdのunitファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-controller-manager \\ --address=0.0.0.0 \\ --cluster-cidr=192.168.5.0/24 \\ --cluster-name=kubernetes \\ --cluster-signing-cert-file=/var/lib/kubernetes/ca.crt \\ --cluster-signing-key-file=/var/lib/kubernetes/ca.key \\ --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ --leader-elect=true \\ --root-ca-file=/var/lib/kubernetes/ca.crt \\ --service-account-private-key-file=/var/lib/kubernetes/service-account.key \\ --service-cluster-ip-range=10.96.0.0/24 \\ --use-service-account-credentials=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Configure the Kubernetes Scheduler
kube-scheduler のkubeconfigを配置します
sudo cp kube-scheduler.kubeconfig /var/lib/kubernetes/
kube-scheduler.service
という、systemdのunitファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-scheduler \\ --kubeconfig=/var/lib/kubernetes/kube-scheduler.kubeconfig \\ --address=127.0.0.1 \\ --leader-elect=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Start the Controller Services
作成したサービスの自動起動設定と、起動をします
{ sudo systemctl daemon-reload sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler }
確認しましょう
kubectl get componentstatuses --kubeconfig admin.kubeconfig
ここでトラブル!
vagrant@master-1:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port?
ほうほう。なんで?
vagrant@master-1:~$ systemctl status kube-apiserver ● kube-apiserver.service - Kubernetes API Server Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled Active: activating (auto-restart) (Result: exit-code) since Wed 2021-10-06 22:30:20 UTC; 3s Docs: https://github.com/kubernetes/kubernetes Process: 7337 ExecStart=/usr/local/bin/kube-apiserver --advertise-address=192.168.5.11 --all Main PID: 7337 (code=exited, status=1/FAILURE)
どうもkube-apiserver が動いてない。sudo 付けてもう一度起動させてみる。
vagrant@master-1:~$ sudo systemctl start kube-apiserver vagrant@master-1:~$ sudo systemctl status kube-apiserver ● kube-apiserver.service - Kubernetes API Server Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled Active: activating (auto-restart) (Result: exit-code) since Sat 2021-10-09 04:35:15 UTC; 2s Docs: https://github.com/kubernetes/kubernetes Process: 30902 ExecStart=/usr/local/bin/kube-apiserver --advertise-address=192.168.5.11 --al Main PID: 30902 (code=exited, status=1/FAILURE) Oct 09 04:35:15 master-1 systemd[1]: kube-apiserver.service: Main process exited, code=exited, Oct 09 04:35:15 master-1 systemd[1]: kube-apiserver.service: Failed with result 'exit-code'.
やっぱダメ
syslog見ると
Oct 9 04:35:57 master-1 systemd[1]: Started Kubernetes API Server. Oct 9 04:35:57 master-1 kube-apiserver[31144]: Error: unknown flag: --kubelet-https Oct 9 04:35:57 master-1 systemd[1]: kube-apiserver.service: Main process exited, code=exited, status=1/FAILURE Oct 9 04:35:57 master-1 systemd[1]: kube-apiserver.service: Failed with result 'exit-code'.
https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/ みてもそんな--kubelet-https
というフラグはないなあ。廃止になったのかな?
--kubelet-https
を消して起動させると、今度はこんなログが
Oct 9 04:53:32 master-1 kube-apiserver[4894]: Error: [service-account-issuer is a required flag, --service-account-signing-key-file and --service-account-issuer are required flags] Oct 9 04:53:32 master-1 systemd[1]: kube-apiserver.service: Main process exited, code=exited, status=1/FAILURE Oct 9 04:53:32 master-1 systemd[1]: kube-apiserver.service: Failed with result 'exit-code'.
やれやれだぜ。一難去ってまた一難
service-account-issuer
と service-account-signing-key-file
が必須と来たか。k8s 1.18以降では、ServiceAccountIssuerDiscoveryというOIDC DiscoveryやJWKsのエンドポイントを提供する機能が追加されて、認証用トークン作成のために鍵が必要らしい。
ここでissueが上がってるな
https://github.com/kelseyhightower/kubernetes-the-hard-way/issues/626
秘密鍵を作成
openssl genrsa -out service-account.key 2048 openssl req -new -key service-account.key -subj "/CN=service-accounts" -out service-account.csr openssl x509 -req -in service-account.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out service-account.crt -days 1000
/etc/systemd/system/kube-apiserver.service
に以下を追記
--service-account-key-file=/var/lib/kubernetes/service-account-key.pem \ --service-account-signing-key-file=/var/lib/kubernetes/service-account-key.pem \ --service-account-issuer=api \
もう1回起動
sudo systemctl daemon-reload sudo systemctl start kube-apiserver
vagrant@master-1:~$ sudo systemctl status kube-apiserver ● kube-apiserver.service - Kubernetes API Server Loaded: loaded (/etc/systemd/system/kube-apiserver.service; enabled; vendor preset: enabled Active: active (running) since Sun 2021-10-10 21:34:46 UTC; 1min 36s ago Docs: https://github.com/kubernetes/kubernetes Main PID: 30706 (kube-apiserver) Tasks: 9 (limit: 2360) CGroup: /system.slice/kube-apiserver.service └─30706 /usr/local/bin/kube-apiserver --advertise-address=192.168.5.11 --allow-priv
よしよし。kubectlでも確認
kubectl get componentstatuses --kubeconfig admin.kubeconfig
vagrant@master-1:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR scheduler Healthy ok etcd-1 Healthy {"health":"true","reason":""} controller-manager Healthy ok etcd-0 Healthy {"health":"true","reason":""}
master-2
に鍵を転送して確認
vagrant@master-2:~$ kubectl get componentstatuses --kubeconfig admin.kubeconfig Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR etcd-1 Healthy {"health":"true","reason":""} etcd-0 Healthy {"health":"true","reason":""} controller-manager Healthy ok scheduler Healthy ok
OKOK!
The Kubernetes Frontend Load Balancer
ここではKubernetes API Server用の外部向けロードバランサを作成します。
vagrant ssh loadbalancer
haproxyをインストールします。
sudo apt-get update && sudo apt-get install -y haproxy
/etc/haproxy/haproxy.cfg
に設定をします。
cat <<EOF | sudo tee /etc/haproxy/haproxy.cfg frontend kubernetes bind 192.168.5.30:6443 option tcplog mode tcp default_backend kubernetes-master-nodes backend kubernetes-master-nodes mode tcp balance roundrobin option tcp-check server master-1 192.168.5.11:6443 check fall 3 rise 2 server master-2 192.168.5.12:6443 check fall 3 rise 2 EOF
sudo service haproxy restart
HTTTPリクエストをして動作確認
curl https://192.168.5.30:6443/version -k
以下のように返ってくればOK
{ "major": "1", "minor": "22", "gitVersion": "v1.22.0", "gitCommit": "c2b5237ccd9c0f1d600d3072634ca66cefdf272f", "gitTreeState": "clean", "buildDate": "2021-08-04T17:57:25Z", "goVersion": "go1.16.6", "compiler": "gc", "platform": "linux/amd64" }
今回はここまで。エラー出たときはびっくりした。
お読みいただきありがとうございました。
Kubernetes The Hard Way On VirtualBox 5日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの5日目。今日はetcdのクラスタを作成します。
Bootstrapping the etcd Cluster
Kubernetesのコンポーネントはステートレスで、クラスタの状態をetcdに保存します。今回は2ノードのetcdクラスタを作成し、高可用性とリモートアクセスの設定をします。
Prerequisites
今回は以下の手順を master-1
と master-2
の両方に行います。
Bootstrapping an etcd Cluster Member
Download and Install the etcd Binaries
公式リポジトリからetcdのバイナリを入手します。
wget -q --show-progress --https-only --timestamping \ "https://github.com/coreos/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz"
入手したファイルを展開し、 etcd
サーバのインストールとコマンドラインユーティリティを置きます。
{ tar -xvf etcd-v3.5.0-linux-amd64.tar.gz sudo mv etcd-v3.5.0-linux-amd64/etcd* /usr/local/bin/ }
Configure the etcd Server
設定ファイルを置くディレクトリを作り、2日目で作成した証明書を置きます
{ sudo mkdir -p /etc/etcd /var/lib/etcd sudo cp ca.crt etcd-server.key etcd-server.crt /etc/etcd/ }
インスタンスの内部IPアドレスは、クライアントからのリクエストを処理し、etcdクラスターピアと通信するために使用されます。 master(etcd)ノードの内部IPアドレスを取得します。
INTERNAL_IP=$(ip addr show enp0s8 | grep "inet " | awk '{print $2}' | cut -d / -f 1)
各etcdメンバーは、etcdクラスター内で一意の名前を持っている必要があります。 現在のコンピューティングインスタンスのホスト名と一致するようにetcdの名前を設定します。
ETCD_NAME=$(hostname -s)
etcd.service
という、systemdのユニットファイルを作成します。
cat <<EOF | sudo tee /etc/systemd/system/etcd.service [Unit] Description=etcd Documentation=https://github.com/coreos [Service] ExecStart=/usr/local/bin/etcd \\ --name ${ETCD_NAME} \\ --cert-file=/etc/etcd/etcd-server.crt \\ --key-file=/etc/etcd/etcd-server.key \\ --peer-cert-file=/etc/etcd/etcd-server.crt \\ --peer-key-file=/etc/etcd/etcd-server.key \\ --trusted-ca-file=/etc/etcd/ca.crt \\ --peer-trusted-ca-file=/etc/etcd/ca.crt \\ --peer-client-cert-auth \\ --client-cert-auth \\ --initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\ --listen-peer-urls https://${INTERNAL_IP}:2380 \\ --listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\ --advertise-client-urls https://${INTERNAL_IP}:2379 \\ --initial-cluster-token etcd-cluster-0 \\ --initial-cluster master-1=https://192.168.5.11:2380,master-2=https://192.168.5.12:2380 \\ --initial-cluster-state new \\ --data-dir=/var/lib/etcd Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Start the etcd Server
{ sudo systemctl daemon-reload sudo systemctl enable etcd sudo systemctl start etcd }
起動状態を確認してみましょう
systemctl status etcd
Verification
動作確認のため、etcdクラスタメンバーを出力してみましょう
sudo ETCDCTL_API=3 etcdctl member list \ --endpoints=https://127.0.0.1:2379 \ --cacert=/etc/etcd/ca.crt \ --cert=/etc/etcd/etcd-server.crt \ --key=/etc/etcd/etcd-server.key
両方のノードで以下のように出力されればOKです。
45bf9ccad8d8900a, started, master-2, https://192.168.5.12:2380, https://192.168.5.12:2379, false 54a5796a6803f252, started, master-1, https://192.168.5.11:2380, https://192.168.5.11:2379, false
今日はここまで!
お読みいただきありがとうございました!
Kubernetes The Hard Way On VirtualBox 4日目
Kubernetesを雰囲気で使わないための修行Kubernetes The Hard Way On VirtualBoxの4日目。今日はデータの暗号化をします。
Generating the Data Encryption Config and Key
Kubernetesはクラスターの状態やアプリケーションのコンフィグなど様々なデータを持ちます。Kubernetesはクラスターのデータを暗号化して保存する機能をサポートしています。
The Encryption Key
暗号化キーを作成し、環境変数に設定します。
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
The Encryption Config File
encryption-config.yaml
というファイルを作成します。
cat > encryption-config.yaml <<EOF kind: EncryptionConfig apiVersion: v1 resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: ${ENCRYPTION_KEY} - identity: {} EOF
encryption-config.yaml
をコントローラーインスタンスにコピーします。
手元のPCでファイルを作成したので、公式手順とは異なってます。
for instance in vagrant@192.168.5.11 vagrant@192.168.5.12 ; do scp encryption-config.yaml ${instance}:~/ done
encryption-config.yaml
を適切な場所に移動させます。
for instance in vagrant@192.168.5.11 vagrant@192.168.5.12 ; do ssh ${instance} sudo mv encryption-config.yaml /var/lib/kubernetes/ done
結果
$ for instance in vagrant@192.168.5.11 vagrant@192.168.5.12 ; do ssh ${instance} sudo mv encryption-config.yaml /var/lib/kubernetes/ done mv: cannot move 'encryption-config.yaml' to '/var/lib/kubernetes/': Not a directory mv: cannot move 'encryption-config.yaml' to '/var/lib/kubernetes/': Not a directory
おっとエラー!どうも /var/lib/kubernetes/
ディレクトリがないらしい。
作れば良いんだろうけど、手順が漏れてたんじゃないかと心配になるな。。。
vagrant@master-1:~$ ls -l /var/lib/ total 136 drwxr-xr-x 4 root root 4096 Aug 27 2020 AccountsService drwxr-xr-x 2 root root 4096 Sep 20 05:47 VBoxGuestAdditions drwxr-xr-x 5 root root 4096 Sep 24 06:16 apt drwxr-xr-x 8 root root 4096 Sep 20 05:46 cloud drwxr-xr-x 2 root root 4096 May 5 2018 command-not-found drwxr-xr-x 2 root root 4096 Sep 20 05:46 dbus drwxr-xr-x 2 root root 4096 Apr 16 2018 dhcp drwxr-xr-x 2 root root 4096 Sep 20 05:46 dkms drwxr-xr-x 7 root root 4096 Sep 24 06:16 dpkg drwxr-xr-x 2 root root 4096 Apr 20 2020 git drwxr-xr-x 3 root root 4096 Aug 27 2020 grub drwxr-xr-x 2 root root 4096 Sep 24 06:16 initramfs-tools drwxr-xr-x 2 landscape landscape 4096 Aug 27 2020 landscape drwxr-xr-x 2 root root 4096 Sep 27 06:25 logrotate drwxr-xr-x 2 root root 0 Sep 27 15:54 lxcfs drwxr-xr-x 2 lxd nogroup 4096 Sep 20 05:46 lxd drwxr-xr-x 2 root root 4096 Aug 27 2020 man-db drwxr-xr-x 2 root root 4096 Apr 24 2018 misc drwxr-xr-x 2 root root 4096 Sep 27 06:25 mlocate drwxr-xr-x 2 root root 4096 Mar 6 2017 os-prober drwxr-xr-x 2 root root 4096 Sep 20 06:18 pam drwxr-xr-x 2 root root 4096 Apr 4 2019 plymouth drwx------ 3 root root 4096 Aug 27 2020 polkit-1 drwxr-xr-x 2 root root 4096 Aug 27 2020 python drwxr-xr-x 18 root root 4096 Sep 20 06:17 snapd drwxr-xr-x 3 root root 4096 Aug 27 2020 sudo drwxr-xr-x 6 root root 4096 Sep 20 05:46 systemd drwxr-xr-x 2 root root 4096 Sep 20 05:46 ubuntu-release-upgrader drwxr-xr-x 3 root root 4096 Sep 24 06:16 ucf drwxr-xr-x 2 root root 4096 Feb 17 2020 unattended-upgrades drwxr-xr-x 2 root root 4096 Sep 20 05:46 update-manager drwxr-xr-x 4 root root 4096 Sep 27 15:50 update-notifier drwxr-xr-x 3 root root 4096 Aug 27 2020 ureadahead drwxr-xr-x 2 root root 4096 Aug 27 2020 usbutils drwxr-xr-x 3 root root 4096 Aug 27 2020 vim
遡ってみたけど、手順漏れはなさそう。ディレクトリ作る手順を追加するか。
for instance in vagrant@192.168.5.11 vagrant@192.168.5.12 ; do ssh ${instance} "sudo mkdir /var/lib/kubernetes/ ; sudo mv encryption-config.yaml /var/lib/kubernetes/" done
今度はちゃんと出来てました。
vagrant@master-1:~$ ls -l /var/lib/kubernetes/ total 4 -rw-rw-r-- 1 vagrant vagrant 240 Sep 27 15:46 encryption-config.yaml
今日はここまで。ずいぶん短いけど週明けはこんなもんでヨシ!
お読みいただきありがとうございました。