zaki work log

作業ログやら生活ログやらなんやら

KubernetesクラスタにPrometheusをOperatorを使ってデプロイしてみた (Helm無し)

OpenShiftだと最初から入ってるけれど、いくつかのマネージドK8sを除いて、EKSやAKSを含めて素のK8sクラスタは初期状態だとメトリクスサーバーはデプロイされていない。
Prometheus Operatorを使うと、メトリクスサーバーとして動作する最近流行りのPrometheusを簡単にデプロイできる。

github.com

とりあえずデプロイ手順について。
設定や使い方はまだあまり分かってないのでそのうち…

環境

ローカルにkindを使ってデプロイした環境。
MetalLB有り。

[zaki@cloud-dev ~]$ kubectl version --short
Client Version: v1.19.2
Server Version: v1.18.2

podの初期状態

[zaki@cloud-dev kube-prometheus]$ kc get pod -A
NAMESPACE            NAME                                                 READY   STATUS    RESTARTS   AGE
kube-system          coredns-66bff467f8-92f5g                             1/1     Running   0          116m
kube-system          coredns-66bff467f8-jx2vk                             1/1     Running   0          116m
kube-system          etcd-prac-cluster-control-plane                      1/1     Running   0          116m
kube-system          kindnet-2bh96                                        1/1     Running   0          116m
kube-system          kindnet-5sbfj                                        1/1     Running   0          116m
kube-system          kindnet-kfw7s                                        1/1     Running   1          116m
kube-system          kube-apiserver-prac-cluster-control-plane            1/1     Running   0          116m
kube-system          kube-controller-manager-prac-cluster-control-plane   1/1     Running   0          116m
kube-system          kube-proxy-gz89m                                     1/1     Running   0          116m
kube-system          kube-proxy-hf466                                     1/1     Running   0          116m
kube-system          kube-proxy-j6cpf                                     1/1     Running   0          116m
kube-system          kube-scheduler-prac-cluster-control-plane            1/1     Running   0          116m
local-path-storage   local-path-provisioner-bd4bb6b75-h4bnb               1/1     Running   0          116m
metallb-system       controller-57f648cb96-vwntj                          1/1     Running   0          91m
metallb-system       speaker-mtvfj                                        1/1     Running   0          91m
metallb-system       speaker-nsh46                                        1/1     Running   0          91m
metallb-system       speaker-z672b                                        1/1     Running   0          91m
sample-app           sample-http-744f56bdc6-bdvt6                         1/1     Running   0          72m
sample-app           sample-http-744f56bdc6-hqc6z                         1/1     Running   0          72m

Prometheus Operatorをデプロイする

github.com

マニフェスト類の取得を手元にcloneする。(ディレクトリ以下全yamlapplyするので)

$ git clone https://github.com/coreos/kube-prometheus
$ cd kube-prometheus

デプロイ

# Create the namespace and CRDs, and then wait for them to be availble before creating the remaining resources
kubectl create -f manifests/setup
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
kubectl create -f manifests/

これだけでデプロイされる。簡単。

実行例

実行すると

[zaki@cloud-dev kube-prometheus]$ # Create the namespace and CRDs, and then wait for them to be availble before creating the remaining resources
[zaki@cloud-dev kube-prometheus]$ kubectl create -f manifests/setup
namespace/monitoring created
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com created
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com created
clusterrole.rbac.authorization.k8s.io/prometheus-operator created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator created
deployment.apps/prometheus-operator created
service/prometheus-operator created
serviceaccount/prometheus-operator created
[zaki@cloud-dev kube-prometheus]$ until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
No resources found
[zaki@cloud-dev kube-prometheus]$ kubectl create -f manifests/
alertmanager.monitoring.coreos.com/main created
secret/alertmanager-main created
service/alertmanager-main created
serviceaccount/alertmanager-main created
servicemonitor.monitoring.coreos.com/alertmanager created
secret/grafana-datasources created
configmap/grafana-dashboard-apiserver created
configmap/grafana-dashboard-cluster-total created
configmap/grafana-dashboard-controller-manager created
configmap/grafana-dashboard-k8s-resources-cluster created
configmap/grafana-dashboard-k8s-resources-namespace created
configmap/grafana-dashboard-k8s-resources-node created
configmap/grafana-dashboard-k8s-resources-pod created
configmap/grafana-dashboard-k8s-resources-workload created
configmap/grafana-dashboard-k8s-resources-workloads-namespace created
configmap/grafana-dashboard-kubelet created
configmap/grafana-dashboard-namespace-by-pod created
configmap/grafana-dashboard-namespace-by-workload created
configmap/grafana-dashboard-node-cluster-rsrc-use created
configmap/grafana-dashboard-node-rsrc-use created
configmap/grafana-dashboard-nodes created
configmap/grafana-dashboard-persistentvolumesusage created
configmap/grafana-dashboard-pod-total created
configmap/grafana-dashboard-prometheus-remote-write created
configmap/grafana-dashboard-prometheus created
configmap/grafana-dashboard-proxy created
configmap/grafana-dashboard-scheduler created
configmap/grafana-dashboard-statefulset created
configmap/grafana-dashboard-workload-total created
configmap/grafana-dashboards created
deployment.apps/grafana created
service/grafana created
serviceaccount/grafana created
servicemonitor.monitoring.coreos.com/grafana created
clusterrole.rbac.authorization.k8s.io/kube-state-metrics created
clusterrolebinding.rbac.authorization.k8s.io/kube-state-metrics created
deployment.apps/kube-state-metrics created
service/kube-state-metrics created
serviceaccount/kube-state-metrics created
servicemonitor.monitoring.coreos.com/kube-state-metrics created
clusterrole.rbac.authorization.k8s.io/node-exporter created
clusterrolebinding.rbac.authorization.k8s.io/node-exporter created
daemonset.apps/node-exporter created
service/node-exporter created
serviceaccount/node-exporter created
servicemonitor.monitoring.coreos.com/node-exporter created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
clusterrole.rbac.authorization.k8s.io/prometheus-adapter created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-adapter created
clusterrolebinding.rbac.authorization.k8s.io/resource-metrics:system:auth-delegator created
clusterrole.rbac.authorization.k8s.io/resource-metrics-server-resources created
configmap/adapter-config created
deployment.apps/prometheus-adapter created
rolebinding.rbac.authorization.k8s.io/resource-metrics-auth-reader created
service/prometheus-adapter created
serviceaccount/prometheus-adapter created
servicemonitor.monitoring.coreos.com/prometheus-adapter created
clusterrole.rbac.authorization.k8s.io/prometheus-k8s created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-k8s created
servicemonitor.monitoring.coreos.com/prometheus-operator created
prometheus.monitoring.coreos.com/k8s created
rolebinding.rbac.authorization.k8s.io/prometheus-k8s-config created
rolebinding.rbac.authorization.k8s.io/prometheus-k8s created
rolebinding.rbac.authorization.k8s.io/prometheus-k8s created
rolebinding.rbac.authorization.k8s.io/prometheus-k8s created
role.rbac.authorization.k8s.io/prometheus-k8s-config created
role.rbac.authorization.k8s.io/prometheus-k8s created
role.rbac.authorization.k8s.io/prometheus-k8s created
role.rbac.authorization.k8s.io/prometheus-k8s created
prometheusrule.monitoring.coreos.com/prometheus-k8s-rules created
service/prometheus-k8s created
serviceaccount/prometheus-k8s created
servicemonitor.monitoring.coreos.com/prometheus created
servicemonitor.monitoring.coreos.com/kube-apiserver created
servicemonitor.monitoring.coreos.com/coredns created
servicemonitor.monitoring.coreos.com/kube-controller-manager created
servicemonitor.monitoring.coreos.com/kube-scheduler created
servicemonitor.monitoring.coreos.com/kubelet created

こんな感じで大量のリソースが作成される。
manifests/setup以下にCRD等があるので、先にkubectl create -f manifests/を実行してしまうとエラーになるので注意。

[zaki@cloud-dev kube-prometheus]$ kc get pod -A
NAMESPACE            NAME                                                 READY   STATUS    RESTARTS   AGE
kube-system          coredns-66bff467f8-92f5g                             1/1     Running   0          138m
kube-system          coredns-66bff467f8-jx2vk                             1/1     Running   0          138m
kube-system          etcd-prac-cluster-control-plane                      1/1     Running   0          138m
kube-system          kindnet-2bh96                                        1/1     Running   0          138m
kube-system          kindnet-5sbfj                                        1/1     Running   0          138m
kube-system          kindnet-kfw7s                                        1/1     Running   1          138m
kube-system          kube-apiserver-prac-cluster-control-plane            1/1     Running   0          138m
kube-system          kube-controller-manager-prac-cluster-control-plane   1/1     Running   1          138m
kube-system          kube-proxy-gz89m                                     1/1     Running   0          138m
kube-system          kube-proxy-hf466                                     1/1     Running   0          138m
kube-system          kube-proxy-j6cpf                                     1/1     Running   0          138m
kube-system          kube-scheduler-prac-cluster-control-plane            1/1     Running   1          138m
local-path-storage   local-path-provisioner-bd4bb6b75-h4bnb               1/1     Running   1          138m
metallb-system       controller-57f648cb96-vwntj                          1/1     Running   0          113m
metallb-system       speaker-mtvfj                                        1/1     Running   0          113m
metallb-system       speaker-nsh46                                        1/1     Running   0          113m
metallb-system       speaker-z672b                                        1/1     Running   0          113m
monitoring           alertmanager-main-0                                  2/2     Running   0          3m37s
monitoring           alertmanager-main-1                                  2/2     Running   0          3m37s
monitoring           alertmanager-main-2                                  2/2     Running   0          3m37s
monitoring           grafana-86445dccbb-gx4p7                             1/1     Running   0          3m38s
monitoring           kube-state-metrics-5b67d79459-z4xh6                  3/3     Running   0          3m38s
monitoring           node-exporter-7rq9n                                  2/2     Running   0          3m38s
monitoring           node-exporter-cfxqr                                  2/2     Running   0          3m38s
monitoring           node-exporter-rzsh5                                  2/2     Running   0          3m38s
monitoring           prometheus-adapter-66b855f564-cst25                  1/1     Running   0          3m38s
monitoring           prometheus-k8s-0                                     3/3     Running   1          3m37s
monitoring           prometheus-k8s-1                                     3/3     Running   1          3m37s
monitoring           prometheus-operator-78fcb48ccf-zbx77                 2/2     Running   0          3m39s
sample-app           sample-http-744f56bdc6-bdvt6                         1/1     Running   0          95m
sample-app           sample-http-744f56bdc6-hqc6z                         1/1     Running   0          95m

dashboardにアクセス

Access the dashboardsを見ればだいたい載ってる。

デプロイすると各Serviceリソースが作成されるので、基本はそれにアクセスすればいい。
今回はドキュメントに沿ってport-forwardを使用。
NodePort ServiceやLoadbalancer Serviceを使ってももちろん良い。

[zaki@cloud-dev kube-prometheus]$ kc get svc -n monitoring 
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
alertmanager-main       ClusterIP   10.99.231.146    <none>        9093/TCP                     14h
alertmanager-operated   ClusterIP   None             <none>        9093/TCP,9094/TCP,9094/UDP   14h
grafana                 ClusterIP   10.106.181.97    <none>        3000/TCP                     14h
kube-state-metrics      ClusterIP   None             <none>        8443/TCP,9443/TCP            14h
node-exporter           ClusterIP   None             <none>        9100/TCP                     14h
prometheus-adapter      ClusterIP   10.96.68.195     <none>        443/TCP                      14h
prometheus-k8s          ClusterIP   10.100.171.252   <none>        9090/TCP                     14h
prometheus-operated     ClusterIP   None             <none>        9090/TCP                     14h
prometheus-operator     ClusterIP   None             <none>        8443/TCP                     14h

Prometheus

[zaki@cloud-dev kube-prometheus]$ kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
Forwarding from 127.0.0.1:9090 -> 9090
Forwarding from [::1]:9090 -> 9090

これで http://localhost:9090/ にアクセスすれば、Prometheusのダッシュボードを参照できる。

f:id:zaki-hmkc:20201011161547p:plain

Targetページを見たところ。

f:id:zaki-hmkc:20201011161600p:plain

Graphのページで、例えばnode_load15のグラフを表示したところ。

f:id:zaki-hmkc:20201011161527p:plain

Grafana

Grafanaも同様にport-forwardで転送設定を行う。

[zaki@cloud-dev kube-prometheus]$ kubectl --namespace monitoring port-forward svc/grafana 3000
Forwarding from 127.0.0.1:3000 -> 3000
Forwarding from [::1]:3000 -> 3000

f:id:zaki-hmkc:20201011161631p:plain

Prometheusと異なり、ログイン画面が表示される。
username: admin、password: adminでログインすると、パスワード変更画面になるので、適当に設定する。

f:id:zaki-hmkc:20201011161703p:plain

ダッシュボードの作成については公式のチュートリアルもあるので、そちらも参照。

f:id:zaki-hmkc:20201011162032p:plain

「Data Sources」から「Prometheus」を選択。

f:id:zaki-hmkc:20201011162101p:plain

URLに、PrometheusのURLを入力。これはGrafanaのpodから見たURLなので、PrometheusのService名を入力すればよい。要はhttp://prometheus-k8s:9090 (あるいはネームスペース名も含めてフルでhttp://prometheus-k8s.monitoring.svc:9090)

f:id:zaki-hmkc:20201011162120p:plain

これで、画面下部の「Save & Test」押下。

f:id:zaki-hmkc:20201011162139p:plain

「Create」メニューの「Dashboard」で新しいパネルの新規作成。

f:id:zaki-hmkc:20201011162401p:plain

なんの値かよくわからないけどグラフが表示されているけど、下部のQueryタブから先ほど設定したデータソースを選択する(Prometheus-1を作ったけど、なんかデフォルトで同じ内容の"Prometheus"があったっぽい笑)

f:id:zaki-hmkc:20201011162639p:plain

そしてもう少し下にある入力欄のEnter a PromQL query (run with Shift+Enter)と表示されてる部分に、Prometheusのときにも表示したnode_load15を入力、表示されてる通りShift+Enter押下する。

f:id:zaki-hmkc:20201011163303p:plain

グラフがプレビューされる。
グラフのタイトルやらいろいろ設定したい箇所はあるけど、とりあえずこれで画面右上の「Apply」を押下すればパネルが完成し、ダッシュボード画面に戻るので保存して名前を付ける。

f:id:zaki-hmkc:20201011163418p:plain

これで、node_load15のメトリクス情報を、Searchダッシュボードからすぐにアクセスできるようになる。
ダッシュボード名を「node load15」にしてしまってるけど、これはパネル名をnode load15にすべきで、ダッシュボード名はもっと別のにすべきだった。

f:id:zaki-hmkc:20201011164205p:plain

metricsサーバー

Prometheusデプロイ前のメトリクスサーバーは以下の通り存在しない。

$ kubectl describe apiservice v1beta1.metrics.k8s.io
Error from server (NotFound): apiservices.apiregistration.k8s.io "v1beta1.metrics.k8s.io" not found

Prometheusをデプロイするとこの通り。

[zaki@cloud-dev kube-prometheus]$ kubectl describe apiservice v1beta1.metrics.k8s.io
Name:         v1beta1.metrics.k8s.io
Namespace:    
Labels:       <none>
Annotations:  <none>
API Version:  apiregistration.k8s.io/v1
Kind:         APIService
Metadata:
  Creation Timestamp:  2020-10-10T15:23:33Z
  Resource Version:    26324
  Self Link:           /apis/apiregistration.k8s.io/v1/apiservices/v1beta1.metrics.k8s.io
  UID:                 1ccaec3c-955e-47f2-8c28-8828743b767e
Spec:
  Group:                     metrics.k8s.io
  Group Priority Minimum:    100
  Insecure Skip TLS Verify:  true
  Service:
    Name:            prometheus-adapter
    Namespace:       monitoring
    Port:            443
  Version:           v1beta1
  Version Priority:  100
Status:
  Conditions:
    Last Transition Time:  2020-10-10T15:23:38Z
    Message:               all checks passed
    Reason:                Passed
    Status:                True
    Type:                  Available
Events:                    <none>

この通り定義が出来ている。

[zaki@cloud-dev ~]$ kubectl top node
NAME                         CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
prac-cluster-control-plane   310m         7%     6495Mi          83%
prac-cluster-worker          253m         6%     6495Mi          83%
prac-cluster-worker2         247m         6%     6495Mi          83%
[zaki@cloud-dev ~]$ kubectl top pod -n kube-system
NAME                                                 CPU(cores)   MEMORY(bytes)
coredns-66bff467f8-92f5g                             3m           52Mi
coredns-66bff467f8-jx2vk                             2m           59Mi
etcd-prac-cluster-control-plane                      23m          228Mi
kindnet-2bh96                                        0m           26Mi
kindnet-5sbfj                                        0m           27Mi
kindnet-kfw7s                                        0m           25Mi
kube-apiserver-prac-cluster-control-plane            54m          1078Mi
kube-controller-manager-prac-cluster-control-plane   15m          129Mi
kube-proxy-gz89m                                     0m           36Mi
kube-proxy-hf466                                     0m           33Mi
kube-proxy-j6cpf                                     0m           33Mi
kube-scheduler-prac-cluster-control-plane            4m           47Mi

また別途まとめたいけど、HPAとかkubectl topが使えるようになってるはず。

thinkit.co.jp

参考情報

coreos.com

qiita.com


ちなみに、今回使ったkube-prometheusと別に、prometheus-operatorというリポジトリもある。
違いは………、正しく理解できてないと思うけど、prometheus-operatorがOperator本体で、kube-prometheusはprometheus-operatorをデプロイするための構成例のカスタムリソース込み、って感じかな…

github.com

あとHelmチャートを使ってもデプロイできるみたい。

github.com

個人環境で無料で利用できるOpenShift 4.x環境4選

クラウドリソースの使用料やサブスクリプションの費用無しに利用することができるOpenShiftを4つ紹介します。
他にもあるかもしれませんが、私が個人環境で触ったことがあるのがこの4つという話です。

用途に応じてお試ししてみてね。
(独断と偏見で難易度(手軽さ):易→難の順に並べています)

バージョンその他諸々は、2020.09.23時点のものです。

(1) Learn OpenShift

  • OpenShiftバージョン: 3.11 ~ 4.5
  • ユーザー登録: 不要
  • 必要なもの: ブラウザのみ
  • 連続利用可能時間: 60分

マウス数クリックで最も簡単に使用できます。
OpenShift: Interactive Learning Portalから、最後(2020年9月時点)にある「OpenShift Playgrounds」を選択し、その先のOpenShiftバージョン毎の「START SCENARIO」で開始できます。

learn.openshift.com

本来は、「OpenShiftを使って〇〇をしてみよう!」というオンラインハンズオンのコースのための環境の一つ(その中でも「OpenShift Playgrounds」は特に課題は設けておらず、自由に使ってみよう、みたいなコース)なので、スペックはそれなり…と思い込んでいたんだけど、ちゃんと見たら結構ありますね。

Capacity:
  cpu:                8
  ephemeral-storage:  125275840Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             24094172Ki
  pods:               250
Allocatable:
  cpu:                7500m
  ephemeral-storage:  114380472129
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             22943196Ki
  pods:               250

RAM24GB…マジか。
(前からこんなにあったっけ?)

OpenShiftに手軽に触れるにはユーザー登録なども何も必要ないので最もお手軽。
場合によってはproxyでガチガチで固められている職b(うわなにをするやめ

Docker Hub + GitHub のようにパブリックに公開しているアプリケーションのビルド&デプロイをゆるーく試してみるには非常に相性が良いです。

ちなみに中身は(おそらく)CodeReady Containerで、ホストOSはCentOS 8で動いています。
プロンプトは$になってるけど、実はrootで動いてるので、作業に必要な追加パッケージがあればyumでインストールもできます。

シングルノードなのでノードをcordondrainしたり、ノード故障関連でのサービス持続性を確認することはできません。

f:id:zaki-hmkc:20200923200958p:plain

あと、KatacodaのOpenShiftシリーズでもほぼ同じものが利用できる。

www.katacoda.com

(2) IBM Open Labs

  • OpenShiftバージョン: 4.3 (K8s version: v1.16.x)
  • ユーザー登録: IBM Cloudのライトアカウントが必要(クレジットカード情報の登録不要)
  • 必要なもの: ブラウザと若干の個人情報(IBM Cloudアカウント登録用)
  • 連続利用可能時間: 7時間 (デフォルトで4時間使用可能・1時間延長を3回できる)

IBM Cloudのアカウント作成後は、これも数クリックでクラスター作成して利用できます。
というか、IBM Cloudのライトアカウント権限で、マネージドOpenShift環境を一定時間無料で使用できる、というもの。

developer.ibm.com

Learn OpenShiftと同じようにブラウザ上でコンソール操作も可能ですが、特徴的なのはクラスターへアクセスするための各種クレデンシャル情報が揃っているので、自分のラップトップなどのocコマンドでもoc loginできます。
手元の環境にocが入っておらず、でもweb上でのコンソール作業はちょっとツライ場合でも、SSHVNC(デスクトップ)で操作用端末へログインすることも可能。
(VNCはnoVNCを使ったブラウザアクセスなので、専用クライアントアプリは不要)

ちなみにVNCでデスクトップへアクセスすると、VS Code(Kubernetes拡張やOpenShift拡張も入っている)もセットアップ済み。

f:id:zaki-hmkc:20200923191500p:plain

運が良ければproxyの深淵からでもアクs(ry

時間も最大7時間使用でき、スペックも検証には十分な4vCPUs・RAM16GBの2ノード構成なので、だいたい何でもできる。(何でもできるとは言っていない)
むしろクラスターが1営業日程度しか使えないのを逆手にとって、クラスター外部に構築したデプロイの自動化設定などの確認に使っても良いかもしれない。

使用するには"Launch Lab"をクリックしてIBM Cloudアカウントでサインインすれば環境が構築されます。

f:id:zaki-hmkc:20200923190900p:plain

再度"Launch Lab"をクリックするとwebのターミナル画面になります。
時間延長やクレデンシャル情報のアクセスは、画面右上の時計アイコンや鍵アイコンから。

f:id:zaki-hmkc:20200923191128p:plain

鍵アイコンをクリックすると、OpenShift・SSHVNCそれぞれの情報を確認できる。

f:id:zaki-hmkc:20200923200036p:plain

参考情報

具体的な利用方法については、戸倉彩さんのQiitaの記事を参考にすると良いです。
現在と画面は若干異なっているけど、流れは同じ。

qiita.com

qiita.com

Learn OpenShiftのPlaygroundsと違ってマルチノードなので、片方のノードをdrainして方肺運転を確認したりもできます。

(3) CodeReady Containers

  • OpenShiftバージョン: 新規インストールは基本的に最新安定板のみ (crc自体のバージョニングはOpenShiftとは独立)
  • ユーザー登録: Red Hat開発者アカウントが必要(pull secret用)
  • 必要なもの: 4vCPUs / RAM9GB / 35GB storageのVM を動かせる程度の人権スペックのPC (OS等詳細はMinimum system requirements)

構成としては、Hyper-V / HyperKit / KVMといった対象OSで使用できる仮想化機能を使って上記スペックのオールインワンのノードVMを作成してそこでOpenShiftを動かすというもの。
ocコマンドはホストOSから実行します。

code-ready.github.io

時間制限のあるクラウドサービスのクラスターと異なり、使わない時間はシャットダウンしておいて続きは明日とかできるけど、30日間で証明書の期限が切れるため、その直前あたりの自動更新する処理が行われる期間に実行されていないと、起動できなくなる (現在は起動時に証明書期限切れだった場合は自動更新されるようになっています)ので注意。
また、アップグレードと言いつつ、既存バージョンを消して新バージョンのインストールなので、時間制限が無いとは言え、長期運用を想定したものではないです。

Minikubeを使ったことある人は、あれのOpenShift版だと思ってもらえればOKです。
Minishiftを使ったことある人は、あれのver4だと思ってもらえればOKです。

必要スペック、去年は確かRAM8GBだったんだけど、要求スペックがいつの間にか上がってるなぁ…


導入例 (on CentOS 7)

$ crc version
CodeReady Containers version: 1.16.0+bf72d3a
OpenShift version: 4.5.9 (embedded in binary)
$ crc setup
$ crc start --pull-secret-file pull-secret.txt

これで起動する。(初回はcrc startでイメージのDLで時間かかる)
具合が悪い場合は--log-level debugで実行すれば何かわかるかもしれない。

デプロイが成功すると、kubeadmなどと同じように最後にoc login -u kubeadmin -p ...というクラスターログインのためのコマンドが表示されるので、それを実行します。
ちなみにパスワードが書かれたファイルは~/.crc/cache/crc_(hypervisor)_*.*.*/kubeadmin-passwordにあるのでいざという時はチェック。

ocコマンドはcrc oc-envを実行すれば「現在使用中のシェルに合わせたexport設定」が表示されるので、その通り実行すればOK。

$ eval $(crc oc-env)

2020.09.23にcrc 1.16.0CentOS Linux release 7.8.2003 (Core)で試した限りでは、「OSをISOイメージからインストールしてyum updateで最新状態にアップデートしておけば」crc setup, crc startでデプロイできました。

[zaki@codeready-ocp4 ~]$ oc version
Client Version: 4.5.9
Server Version: 4.5.9
Kubernetes Version: v1.18.3+6c42de8
[zaki@codeready-ocp4 ~]$ oc get node -o wide
NAME                 STATUS   ROLES           AGE   VERSION           INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                                                       KERNEL-VERSION                 CONTAINER-RUNTIME
crc-zqfk6-master-0   Ready    master,worker   9d    v1.18.3+6c42de8   192.168.126.11   <none>        Red Hat Enterprise Linux CoreOS 45.82.202009040230-0 (Ootpa)   4.18.0-193.14.3.el8_2.x86_64   cri-o://1.18.3-12.rhaos4.5.git99f5d4a.el8

導入例 (on Windows 10 pro)

PS C:\Users\zaki> crc setup
PS C:\Users\zaki> crc start --pull-secret-file .\Downloads\pull-secret.txt

やることはLinuxと一緒。
ver 1.2の頃はちょっと工夫が必要だったけど、普通に動くようになっていた。

PS C:\Users\zaki> crc oc-env
$Env:PATH = "C:\Users\zaki\.crc\bin\oc;$Env:PATH"
# Run this command to configure your shell:
# & crc oc-env | Invoke-Expression
PS C:\Users\zaki> & crc oc-env | Invoke-Expression
PS C:\Users\zaki> oc version
Client Version: 4.5.9
Server Version: 4.5.9
Kubernetes Version: v1.18.3+6c42de8
PS C:\Users\zaki>
PS C:\Users\zaki>
PS C:\Users\zaki> oc get node -o wide
NAME                 STATUS   ROLES           AGE   VERSION           INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                                                       KERNEL-VERSION                 CONTAINER-RUNTIME
crc-zqfk6-master-0   Ready    master,worker   9d    v1.18.3+6c42de8   192.168.126.11   <none>        Red Hat Enterprise Linux CoreOS 45.82.202009040230-0 (Ootpa)   4.18.0-193.14.3.el8_2.x86_64   cri-o://1.18.3-12.rhaos4.5.git99f5d4a.el8

※ 手元の環境で試してみるとoc loginするためのapi.crc.testingcrc startだけで名前解決されたけど、処理中にアクセスが必要なoauth-openshift.apps-crc.testingの名前解決がなぜか127.0.0.1になってうまくいかなかったので、hostsに記述して回避した。

172.17.200.210 oauth-openshift.apps-crc.testing

--enable-experimental-features

今気づいたんだけど、なんかオプション追加されてました。

$ crc setup --help

Flags:
      --enable-experimental-features   Allow the use of experimental features
  -h, --help                           help for setup

以前あった--vm-driver string(hypervとかのハイパーバイザを指定する)が無くなってかわりにexperimental featuresがあるんだけど、なんかワクワクしますね、これ。

参考情報

ver1.0前後で試したときの情報だけど、手順は変わってないみたい。
Hyper-Vの場合だとあらかじめ"crc"という名前で仮想スイッチを作っておくバッドノウハウが不要になったみたい。

(4) OKD on ベアメタル他

  • OpenShiftバージョン: 制限なし
  • ユーザー登録: 不要 (pull secretは使用しない…らしい。構築時にセットしてたので未確認)
  • 必要なもの: 構成によっていろいろ…例としてベアメタルであればMinimum resource requirementsの通り。(storageは120GBとなっているが用途次第なので節約したければ半分以下でも良い)
    • bootstrap: 4vCPUs / RAM16GB (x1)
    • control plane: 4vCPUs / RAM16GB (x3)
    • compute: 2vCPUs / RAM8GB (x2)

これは「OpenShiftがどんなモノなのかチョットダケ試してみたい」という人にはお勧めしない笑
OpenShiftを業務環境で触っており、学習・検証用に自宅などのプライベート環境にも構築したい人にはお勧め。
また、構築手順もOpenShiftと同様のため、特に「構築そのものの素振り」にもかなりお勧め。

使い方としては、IBM Open Labsのように1日で環境が無くなると困るような場合やアプリやデータの機密性が高くてクラウドには載せられないという事情があるような場合は有用。
スペックについても最も自由度が高いので、OpenShiftのサブスクリプションだけが無い逸般の誤家庭での利用であれば何でもできる。(何でもできるとは言っていない)

証明書の期限切れについてはCodeReady Containersと同様なので注意。
(そもそもOpenShiftも同様)

それと、OKDは厳密にはOpenShiftとは異なります。
2年くらい前までは「OpenShift Origin」という名前で、OpenShiftのコミュニティ版・アップストリーム版という位置づけでリリースされていましたが、OKD4のGAリリースのタイミングで関連性が変更され兄弟関係となりました。

OpenShiftがRed Hat Enterprise Linux CoreOSをノードOSに使用するのに対して、OKD4はFedora CoreOSを使用します。

参考情報

[Ansible] Arista EOSのcEOS-labコンテナにAnsibleでeos_factsするまでいろいろハマったこと

一昨日つくったcEOS-labコンテナにAnsibleのeosモジュール使ってアクセスする。
使うモジュールはひとまず情報収集のeos_factsを使用。

zaki-hmkc.hatenablog.com

ネットワーク初心者の自分にはハマりポイントが大量にあったので色々と備忘録。
ポイントは「相手がコンテナであることは忘れろ。Linuxでも無い」だった笑

答え

コンテナ内22/TCPのpublish設定

(未確認だけど原理的に)無くても(コンテナのIPアドレスチェックして直接接続にいけば多分)動くっちゃ動く(と思う)けど分かりやすいように。

$ docker create --name=ceos-4-21 --privileged -p 25022:22 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:4.21.12M /sbin/init

こんな感じでコンテナを作り直す。(25022は適当)
要はcEOS-Labコンテナ内ではsshdが動いてるので、それを外からアクセスできるようにする。

[zaki@cloud-dev dev]$ docker exec -it ceos-4-21 bash
bash-4.3# lsof -i:22
COMMAND  PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
xinetd  1412 root    5u  IPv4 3691233      0t0  TCP *:ssh (LISTEN)
xinetd  1412 root    6u  IPv6 3691234      0t0  TCP *:ssh (LISTEN)
sshd    2981 root    3u  IPv4 3729852      0t0  TCP 172.17.0.2:ssh->172.17.0.1:directplaysrvr (ESTABLISHED)
sshd    2981 root    4u  IPv4 3729852      0t0  TCP 172.17.0.2:ssh->172.17.0.1:directplaysrvr (ESTABLISHED)
bash-4.3# ss -anptl
(省略)

ちなみにcEOS-lab 4.21.12Mの土台はFedora 18だった

bash-4.3# cat /etc/redhat-release
Fedora release 18 (Spherical Cow)

cEOS-lab側設定

Cliでアクセスするユーザー作成&enableが出来る権限設定を行う。

bash-4.3# Cli
localhost>enable
localhost#configure
localhost(config)#username lab-user privilege 15 secret p@ssword

これで、外部からsshしつつenableで昇格も可能。

[zaki@cloud-dev ~]$ ssh lab-user@localhost -p 25022
Password: 
localhost>enable 
localhost#

paramiko

paramikoが必要なのでAnsibleコントロールノードにpipでインストールする。
(別件で入れてたので遭遇しなかったけど、無いと「paramikoがないよ」ってエラーになる)

TASK [gather facts] 
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  msg: 'paramiko is not installed: No module named ''paramiko'''

Ansible

playbook

- hosts: eos
  gather_facts: no

  tasks:
  - name: gather facts
    eos_facts:
      gather_subset: all
    register: eosfacts

  - debug:
      msg: "{{eosfacts}}"

inventory

[eos]
localhost

group_vars/eos.yml

ansible_connection: network_cli
ansible_network_os: eos
ansible_port: 25022

ansible_user: lab-user
ansible_password: p@ssword

ansible_become: yes
ansible_become_method: enable

あとは必要に応じてansible.cfgstdout_callback = yamlなど。

ファイルは一式GitHubに置いてる。

github.com

実行

$ ansible-playbook -i inventory.ini playbook.yml

PLAY [eos] *****************************************************************************************************************************************************

TASK [gather facts] ********************************************************************************************************************************************
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
ok: [localhost]

TASK [debug] ***************************************************************************************************************************************************
ok: [localhost] => 
  msg:
    ansible_facts:
      ansible_net_all_ipv4_addresses: []
      ansible_net_all_ipv6_addresses: []
      ansible_net_api: cliconf
      ansible_net_config: |-
        ! Command: show running-config
        ! device: localhost (cEOSLab, EOS-4.21.12M-18662095.42112M (engineering build))
        !
        transceiver qsfp default-mode 4x10G
        !
        spanning-tree mode mstp
        !
        no aaa root
        !
        username lab-user privilege 15 secret sha512 <*** hash-value ***>
        username test01 privilege 10 secret sha512 <*** hash-value ***>
        username test02 privilege 15 secret sha512 <*** hash-value ***>
        !
        no ip routing
        !
        end
      ansible_net_filesystems:
      - 'file:'
      - 'flash:'
      - 'system:'
      ansible_net_fqdn: localhost
      ansible_net_gather_network_resources: []
      ansible_net_gather_subset:
      - hardware
      - default
      - interfaces
      - config
      ansible_net_hostname: localhost
      ansible_net_interfaces: {}
      ansible_net_memfree_mb: 1179.5234375
      ansible_net_memtotal_mb: 7802.80859375
      ansible_net_model: cEOSLab
      ansible_net_neighbors: {}
      ansible_net_python_version: 2.7.5
      ansible_net_serialnum: ''
      ansible_net_system: eos
      ansible_net_version: 4.21.12M-18662095.42112M (engineering build)
      ansible_network_resources: {}
      discovered_interpreter_python: /usr/bin/python
    changed: false
    failed: false
    warnings:
    - default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards

PLAY RECAP *****************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

usernameのところは、作成したユーザーがリストされている。

勘違いしてたこと

コンテナなんだからconnection=docker使う?

昨日書いた記事はこれの準備のつもりだったけど、ハズレでした。

ちなみにansible_connection=dockerで接続しようとするとEOSとして扱おうとしてくれず、そもそも組み合わせ不可となる。

TASK [gather facts] 
fatal: [localhost]: FAILED! => changed=false 
  msg: Connection type docker is not valid for this module

正解は

ansible_connection: network_cli
ansible_network_os: eos

参考

docs.ansible.com

tekunabe.hatenablog.jp

ssh接続用のユーザーをuseraddで用意する

デフォルトだと/etc/passwdを見る限り接続に使えそうなユーザーがいないので、useraddで接続用ユーザーを作ったのですが、これもハズレ。

bash-4.3# useradd -m ansible
bash-4.3# passwd ansible

これで作ったアカウント情報をAnsibleで設定して実行しても

TASK [gather facts] ********************************************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  msg: unable to set terminal parameters

って感じ。
これ、-vvv付けても追加されるスタックトレース

The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
  File "/tmp/ansible_eos_facts_payload_cxWm95/ansible_eos_facts_payload.zip/ansible/module_utils/network/common/network.py", line 229, in get_capabilities
    capabilities = Connection(module._socket_path).get_capabilities()
  File "/tmp/ansible_eos_facts_payload_cxWm95/ansible_eos_facts_payload.zip/ansible/module_utils/connection.py", line 185, in __rpc__
    raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
fatal: [localhost]: FAILED! => changed=false 

って感じでホントよくわからんかったけど、msgで出ているログは多分ここ。

github.com

    def on_open_shell(self):
        try:
            for cmd in (b'terminal length 0', b'terminal width 512'):
                self._exec_cli_command(cmd)
        except AnsibleConnectionFailure:
            raise AnsibleConnectionFailure('unable to set terminal parameters')

というのも、useraddで作ったユーザーでsshで入ってシェルのhistory(Ctrl-p)を見ると、terminal length 0を叩いた形跡があり、でもterminalなんてコマンドは無いのでsshのレイヤーでは接続に成功してるけどAnsibleの実行に失敗してることがわかる。
(ちなみに、コンテナ内の/var/log/messagesを見ても、Ansible実行のタイミングでsshstatus=0で終了している)

[zaki@cloud-dev ~]$ ssh ansible@localhost -p 25022
Password: 
Last login: Mon Sep 21 01:06:11 2020 from 172.17.0.1

Arista Networks EOS shell

[ansible@localhost ~]$
[ansible@localhost ~]$ history | grep terminal
    1  terminal length 0
    3  terminal length 0
    9  terminal length 0
   10  history | grep terminal
[ansible@localhost ~]$ terminal length 0
-bash: terminal: command not found

じゃあこのコマンドってどこで実行するのかっていうと、Cliのシェル上で実行するのね。

[ansible@localhost ~]$ Cli
localhost>terminal length 0
Pagination disabled.
localhost>terminal length 512
Pagination set to 512 lines.

つまりAnsibleの実行も、接続したときにCliが起動してるのを期待してるというわけ。
そこで、最初からCliが起動してればいいじゃんということで、chshでログインシェルを変更してみる。

bash-4.3# chsh ansible
Changing shell for ansible.
New shell [/bin/bash]: /usr/bin/Cli
Shell changed.
bash-4.3# chsh ansible
Changing shell for ansible.

これで素のsshでもAnsible実行でも、「作成したユーザーでssh接続しつつEOSのシェル(Cli)でコマンドを打てる」というところまでは動く。

ただし、、、

[zaki@cloud-dev ~]$ ssh ansible@localhost -p 25022
Password: 
Last login: Mon Sep 21 01:14:24 2020 from 172.17.0.1
localhost>show version
 cEOSLab
Hardware version:    
Serial number:       
System MAC address:  Not available

Software image version: 4.21.12M-18662095.42112M (engineering build)
Architecture:           i386
Internal build version: 4.21.12M-18662095.42112M
Internal build ID:      3266415c-55a9-403c-a020-777efe5ff9aa

cEOS tools version: 1.1

Uptime:                 0 weeks, 5 days, 11 hours and 51 minutes
Total memory:           7990076 kB
Free memory:            1296380 kB

localhost>enable 
% Cannot authenticate unknown uid 1000

こんな感じでenableで特権を得られなかった。

ansible-playbookでもこんな感じ。

TASK [gather facts] 
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  msg: 'unable to elevate privilege to enable mode, at prompt [b''\nlocalhost>''] with error: failed to elevate privilege to enable mode still at prompt [b''\nlocalhost>'']'

作成したユーザーの昇格設定がわからなかったのと、rootユーザーをchshしても回避できそうだけど、さすがにその設定は不都合が多すぎの予感がしたので別の方法が無いかと思った。

参考

tekunabe.hatenablog.jp

github.com

github.com


正解は、OSのユーザーを作成するのでなく、EOSのユーザー(って言い方でいいのかな?)を作成すればOK。
権限も設定できるし、作成したユーザー名で外部からsshもできる。

ユーザー作成は一旦rootで(docker exec -itでシェル起動して)Cliコマンドで、configureを起動してからusernameコマンドを使用する。

その際、OSユーザーと同名のアカウントは作成できない模様。

localhost#username ansible privilege 15 secret ansible
% Invalid input
localhost#configure
localhost(config)#username ansible privilege 15 secret ansible
% Unable to create reserved username 'ansible'. Please try another.
localhost(config)#username test01 privilege 10 secret test01
localhost(config)#username test02 privilege 15 secret test02
localhost(config)#username lab-user privilege 15 secret p@ssword

これで、test01test02lab-usersshで接続すればCliが起動する。
(これらのユーザーは/etc/passwdには記載されない)

参考

www.infraexpert.com

beginners-network.com

その他関連情報

[Ansible] Connectionプラグインを使ってDockerコンテナを対象に接続・処理する

2021.05.23、docker_container_execモジュールについて追記


Ansibleの処理対象としてDockerコンテナを指定する。 sshを使用しないので、接続先(=コンテナ内)でsshサーバーは不要だけど、コンテナ内にPythonは必要。

お試しということで、Python:3イメージを使う。

対象コンテナ起動

[zaki@cloud-dev ~]$ docker run -d --name=sample-py-container python:3 tail -f /dev/null
5ed36892e53e70e9945883e662d76a9e93f1734924b5ef3fd7197203cfb8bcc0

これでPythonインタプリタ入りの何もしないコンテナが実行される。
ansible_hostで指定するのでコンテナ名も指定しておく (指定しない場合でも、コンテナID(↑だと5ed3とか)でも指定可能)。

[zaki@cloud-dev ~]$ docker exec -it sample-py-container bash
root@5ed36892e53e:/# python --version
Python 3.8.5

playbook

例なのでディレクトリ作ってlsの結果を出力してみる。

- hosts: docker
  gather_facts: no

  tasks:
  - name: create directory
    file:
      path: /zzz
      state: directory
      mode: '0755'

  - name: command sample
    shell: hostname; ls -C /
    register: result_ls

  - name: print result
    debug:
      msg: "{{ result_ls }}"

hosts: dockerと書いてるけど、これは次のinventoryで定義する。

inventory

[docker]
localhost  ansible_connection=docker ansible_host=sample-py-container

localhostって書いてはいるけど、後ろにansible_host=で接続先を明示的に指定してるので、このホスト名は特に意味はない(極端な話、名前解決できないzzzzとかでも動く)。要は後続の設定でAnsible実行ホスト上で動いてるDockerのコンテナに接続に行く。

重要なのはansible_connection=dockerで、接続プラグインdockerを指定すること。
それから、対象コンテナをansible_hostでコンテナ名またはコンテナIDを指定する。

sample-py-containerは、コンテナ起動時に--nameで指定したコンテナ名。
再掲だけど、コンテナ名を指定しない場合はコンテナIDでもOK。
要はdocker start <container-name or container-id>とかで指定するのと同じようにコンテナを一意に指定できる識別子。

実行

(dev) [zaki@cloud-dev connection-docker]$ ansible-playbook -i inventory.ini playbook.yml

PLAY [docker] ****************************************************************************************

TASK [create directory] ******************************************************************************
[WARNING]: Platform linux on host localhost is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
changed: [localhost]

TASK [command sample] ********************************************************************************

changed: [localhost]

TASK [print result] **********************************************************************************

ok: [localhost] =>
  msg:
    changed: true
    cmd: hostname; ls -C /
    delta: '0:00:00.409172'
    end: '2020-09-20 12:23:46.157786'
    failed: false
    rc: 0
    start: '2020-09-20 12:23:45.748614'
    stderr: ''
    stderr_lines: []
    stdout: |-
      5ed36892e53e
      bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
      boot  etc  lib   media  opt  root  sbin  sys  usr  zzz
    stdout_lines:
    - 5ed36892e53e
    - "bin   dev  home  lib64\tmnt  proc  run\t srv  tmp  var"
    - "boot  etc  lib\t media\topt  root  sbin  sys  usr  zzz"

PLAY RECAP *******************************************************************************************

localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

ちゃんと動いた。

接続情報

ちなみに、実行時に-vvvくらいまで付けると

<sample-py-container> EXEC ['/usr/bin/docker', b'exec', b'-i', 'sample-py-container', '/bin/sh', '-c', '/bin/sh -c \'echo PLATFORM; uname; echo FOUND; command -v \'"\'"\'/usr/bin/python\'"\'"\'; command -v \'"\'"\'python3.7\'"\'"\'; command -v \'"\'"\'python3.6\'"\'"\'; command -v \'"\'"\'python3.5\'"\'"\'; command -v \'"\'"\'python2.7\'"\'"\'; command -v \'"\'"\'python2.6\'"\'"\'; command -v \'"\'"\'/usr/libexec/platform-python\'"\'"\'; command -v \'"\'"\'/usr/bin/python3\'"\'"\'; command -v \'"\'"\'python\'"\'"\'; echo ENDFOUND && sleep 0\'']

という感じで内部ではdocker execを実行しているのが確認できるので、ssh接続のときのような認証情報を必要としていない。

警告は何?

Python:3使ってるのになんで?と思ったけど、デフォルトで使用する/usr/bin/pythonが2.7だったw

(dev) [zaki@cloud-dev connection-docker]$ docker exec -it sample-py-container bash
root@5ed36892e53e:/# /usr/bin/python --version
Python 2.7.16
root@5ed36892e53e:/# /usr/bin/python3 --version
Python 3.7.3

これは、ansible.cfgに以下を追加すれば、接続先(=コンテナ内)のインタプリタ/usr/bin/python3を使うようになるので警告も消える。

[defaults]
stdout_callback = yaml
interpreter_python = /usr/bin/python3

最初にpython --versionでバージョン確認したはずなんだけどなー。。。

root@5ed36892e53e:/# which python
/usr/local/bin/python

なるほどねー。。。

確認

ちゃんとコンテナの中でPlaybookの内容が処理されました。

(dev) [zaki@cloud-dev connection-docker]$ ls -F /
bin@   dev/  home/  lib64@  mnt/  proc/  run/   srv/  tmp/  var/
boot/  etc/  lib@   media/  opt/  root/  sbin@  sys/  usr/
(dev) [zaki@cloud-dev connection-docker]$ docker exec -it sample-py-container ls -F /
bin/   dev/  home/  lib64/  mnt/  proc/  run/   srv/  tmp/  var/
boot/  etc/  lib/   media/  opt/  root/  sbin/  sys/  usr/  zzz/

環境

(dev) [zaki@cloud-dev connection-docker]$ ansible-playbook --version
ansible-playbook 2.9.10
  config file = /home/zaki/src/ansible-sample/connection-docker/ansible.cfg
  configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/zaki/.local/lib/python3.6/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
(dev) [zaki@cloud-dev connection-docker]$ ansible-config dump --only-changed
DEFAULT_STDOUT_CALLBACK(/home/zaki/src/ansible-sample/connection-docker/ansible.cfg) = yaml

(参考)

Connection Plugins

docs.ansible.com

サンプルplaybook

github.com

コンテナ内にPythonが無い場合

コネクションプラグインにデフォルトのsshでなくdockerを指定することで、Ansibleの基本要件である「SSHサーバーが動いていてPythonインタプリタが入ってればターゲットノードとして処理可能」のうち、「SSH接続」のかわりに「DockerのAPI接続」を使うようにしている。
つまり、対象のターゲットノードにPythonが必要という要件はそのまま残っているので、コンテナ内にPythonインタプリタが無い場合は処理できない。

raw

例ではpythonイメージを使ったので普通にAnsible実行できるが、Pythonインタプリタが入ってないイメージ(AlpineやDebianベースのイメージは基本入ってないっぽい)も当然あり、その場合は通常のAnsibleモジュールは使用できない。
そのようなコンテナに対する操作をAnsibleを使った処理にどうしても組み込みたい場合は、rawモジュールを使うなどする。
rawモジュールはPythonインタプリタが無くても使うことができ、dockerコネクションを使って接続した上でdocker execでコンテナ内のシェル起動してから実行できるコマンド類をAnsibleを使って実行することが可能。

docs.ansible.com

docker_container_exec

community.dockerコレクションのver 1.5.0以降では、docker_container_execモジュールが新しく使えるようになっている。
これはコネクションプラグインを使った接続でなく、(基本的には)ターゲットノード上で動作しているDockerエンジンを対象に、このモジュールで指定したコンテナ内で指定のコマンドを実行することができる。

docs.ansible.com

docker exec相当のコンテナ内でコマンドを実行するだけでよく、新しいバージョンのコレクションを使用できるのであれば、このモジュールを使うのが一番楽かもしれない。

Arista EOSの検証用コンテナcEOS-labで"Cli"コマンドを叩けるか試した

cEOS-labコンテナを動かしてその先でいろいろ動かしてみるはずが、動かすかどうかでつまづいてしまったのでその作業ログを。
Cliコマンドとか分かってないので、動かし方を分かってない。
※ コンテナ自体は動いているので、Cli以外の方法で触るものだろうとは思っている(がREADMEに書かれてないので…その、なんというか、あれ)

Software Download - Arista

ちなみに、ダウンロードできるコンテナイメージは2020.09.19時点でこんな感じ。

f:id:zaki-hmkc:20200919215217p:plain

手順書

安定と安心のてくなべを参考にさせていただきました。

tekunabe.hatenablog.jp

1年半以上前の記事なので公式のバージョンもそこそこ更新されており、Cliコマンドが使えるか否かという点でいうと、以下の通りだった。

バージョン Cliが使えるか否か
cEOS-lab-4.20.5F 試してない
cEOS-lab-4.21.12M
cEOS-lab-4.22.7M
cEOS64-lab-4.23.4.2M 試してない
cEOS-lab-4.23.4.2M ×
cEOS64-lab-4.23.4.2M ×
cEOS-lab-4.24.2.2F ×
cEOS64-lab-4.24.2.2F ×

※ ホントはこんな「全バージョンで実行できるか否かの一覧作成」をするつもりは全くなかったんだけど…笑

readme

現時点で公開されている「cEOS-lab-README-generic.txt」は、

(This document uses 4.21.0F as an example, but the following instructions apply to all releases starting 4.21.0F)

となっており、4.21ベースの模様。

cEOS64-lab-4.24.2.2F (※動かせなかった)

バージョンがだいぶ更新されており、4.22以降は64bit版っぽいイメージが用意されている。 せっかくなので新しい"cEOS64-lab-4.24.2.2F.tar.xz"を選択。

chromeでDLしたら.xzが溶けてファイル名がcEOS64-lab-4.24.2.2F.tarになったりしたけど、実態はXZ compressed dataなので注意

$ file cEOS64-lab-4.24.2.2F.tar 
cEOS64-lab-4.24.2.2F.tar: XZ compressed data

といっても、そのままdocker importできる。

docker import

$ docker import cEOS64-lab-4.24.2.2F.tar ceos:latest
sha256:8434c650f68e3612d5ae0614e82d97d5a663026df41ef9744f265f45731087a0
(dev) [zaki@cloud-dev image]$ docker images ceos
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
ceos                latest              8434c650f68e        About a minute ago   1.77GB

ちなみにこの状態でパラメタ無しでコンテナ起動しようとしても

(dev) [zaki@cloud-dev image]$ docker run ceos
docker: Error response from daemon: No command specified.
See 'docker run --help'.

docker create

443は使用中なので、代わりに25443を使う

$ docker create --name=ceos --privileged -p 25443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:latest /sbin/init
875ec872dae3093b5923cc825c36da77adfd167de1f273a09049ba2336859bf2
(dev) [zaki@cloud-dev image]$ docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS                      PORTS                       NAMES
875ec872dae3        ceos:latest                  "/sbin/init"             30 seconds ago      Created                                                 ceos

networkの追加

(dev) [zaki@cloud-dev image]$ sudo docker network create net1
1e7a6f36bebc4d4e8d890766cc60a599c0208d439b2615f5f9d2afafa63c1f79
(dev) [zaki@cloud-dev image]$ sudo docker network connect net1 ceos

run

(dev) [zaki@cloud-dev image]$ docker start ceos
ceos
$ sudo docker exec -it ceos cli
OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"cli\": executable file not found in $PATH": unknown

無いらしい。

(dev) [zaki@cloud-dev image]$ sudo docker exec -it ceos sh
sh-4.2# cli
sh: cli: command not found
sh-4.2# Cli
sh: Cli: command not found

shはあるけど、Cliは無いらしい。

sh-4.2# Cli
CliCtrl              CliRelay             CliRelaySwitchAgent  CliShell           

似たコマンドでCliShellはあるが、

sh-4.2# CliShell 
Traceback (most recent call last):
  File "/usr/bin/CliShell", line 408, in <module>
    main()
  File "/usr/bin/CliShell", line 390, in main
    cliShell.setupConnection()
  File "/usr/bin/CliShell", line 123, in setupConnection
    ctty, self.pts_ )
  File "/usr/lib/python2.7/site-packages/CliShellLib.py", line 260, in connectToBackend
    sock, signalSock = self._connectToBackend( sysname, argv, env, uid, gid, ctty )
  File "/usr/lib/python2.7/site-packages/CliShellLib.py", line 226, in _connectToBackend
    time.sleep( 0.1 )
KeyboardInterrupt

起動しても何も応答がなく、Ctrl-cで停止するくらいしか操作法がよくわからん。


cEOS-lab-4.21.12M (動かせた)

ちょっとお手上げだったので、同じバージョンの4.21で試そう。

(dev) [zaki@cloud-dev image]$ docker import cEOS-lab-4.21.12M.tar ceos:4.21.12M
sha256:e56ad1d7eebc792d9ca66dab41557e337f2d6a74c91340767816a24e820b3d71
(dev) [zaki@cloud-dev image]$ docker create --name=ceos-4-21 --privileged -p 24443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:4.21.12M /sbin/init
1511077dd3162a3be3865ed50d000e1494aad388db746d92b30aad45c0a4cd72
(dev) [zaki@cloud-dev image]$ docker start ceos-4-21
ceos-4-21
(dev) [zaki@cloud-dev image]$ docker exec -it ceos-4-21 Cli
localhost>

あっ、うごいた

localhost>show version
 cEOSLab
Hardware version:    
Serial number:       
System MAC address:  Not available

Software image version: 4.21.12M-18662095.42112M (engineering build)
Architecture:           i386
Internal build version: 4.21.12M-18662095.42112M
Internal build ID:      3266415c-55a9-403c-a020-777efe5ff9aa

cEOS tools version: 1.1

Uptime:                 0 weeks, 3 days, 20 hours and 15 minutes
Total memory:           7990076 kB
Free memory:            1943660 kB

localhost>
localhost>show running-config
% Invalid input (privileged mode required)
localhost>en
localhost#show running-config
! Command: show running-config
! device: localhost (cEOSLab, EOS-4.21.12M-18662095.42112M (engineering build))
!
transceiver qsfp default-mode 4x10G
!
spanning-tree mode mstp
!
no aaa root
!
no ip routing
!
end
localhost#

動いてますね

cEOS-lab-4.24.2.2F (ダメ)

最初にうまくいかなかったバージョンの64がないバージョン。

$ docker import cEOS-lab-4.24.2.2F.tar ceos:4.24.2.2F
sha256:3f1567aa671d0aac9c83ac952e88a4d75baf65f44684f855216e3149b7f3ee3e
(dev) [zaki@cloud-dev image]$ docker create --name=ceos-4-24 --privileged -p 23443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:4.24.2.2F /sbin/init
13896de736fbfa703942ec98ed447af12b0413b437dc8f67afbe70c411d1f342
(dev) [zaki@cloud-dev image]$ docker start ceos-4-24
ceos-4-24
(dev) [zaki@cloud-dev image]$ docker exec -it ceos-4-24 sh
sh-4.2# Cl
CliCtrl              CliRelay             CliRelaySwitchAgent  CliShell             CloudHa    

あー、64は関係なくて、4.24はCliコマンドが無いのね。

cEOS64-lab-4.23.4.2M (ダメ)

Fがダメ?

$ docker import cEOS64-lab-4.23.4.2M.tar ceos:4.23.4.2M64
sha256:4f838740b554971259e4086f6e48f70044e721a944bc33f4ae9d67e9ac6cac9f
$ docker create --name=ceos-4-23 --privileged -p 22443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:4.23.4.2M64 /sbin/init
764f96dfe0827fe9a142bddbbf24106e8524b7175f2731656e45088a0b5d08ea
(dev) [zaki@cloud-dev image]$ docker start ceos-4-23
ceos-4-23
(dev) [zaki@cloud-dev image]$ docker exec -it ceos-4-23 Cli
OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"Cli\": executable file not found in $PATH": unknown
(dev) [zaki@cloud-dev image]$ docker exec -it ceos-4-23 sh
sh-4.2# Cl
CliCtrl              CliRelay             CliRelaySwitchAgent  CliShell             CloudHa     

なるほど、コマンド体系が違うかもしれん。

cEOS-lab-4.22.7M (Cli動く)

$ docker import cEOS-lab-4.22.7M.tar ceos:4.22.7M
sha256:a10db96332046efd58c578e3098949fc63cf8b6bb6a22e022c1b016eb5a587eb
(dev) [zaki@cloud-dev image]$ docker create --name=ceos-4-22 --privileged -p 21443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:4.22.7M /sbin/init
d8dd9cbe761a2c4df5fc31fdcc3ee5ea0f4f40c490d0801c20779c0b71fb2ecd
(dev) [zaki@cloud-dev image]$ docker start ceos-4-22
ceos-4-22
(dev) [zaki@cloud-dev image]$ docker exec -it ceos-4-22 Cli
localhost>

これは動くのか!

localhost>show version
 cEOSLab
Hardware version:    
Serial number:       
System MAC address:  Not available

Software image version: 4.22.7M-18857350.4227M (engineering build)
Architecture:           i686
Internal build version: 4.22.7M-18857350.4227M
Internal build ID:      7980773b-992a-4e45-b4ef-66a400409260

cEOS tools version: 1.1

Uptime:                 0 weeks, 3 days, 22 hours and 42 minutes
Total memory:           7990076 kB
Free memory:            950376 kB

localhost>

cEOS-lab-4.23.4.2M (だめ。Cliなし)

(dev) [zaki@cloud-dev image]$ docker import cEOS-lab-4.23.4.2M.tar ceos:4.23.4.2M
sha256:75effb6eefa838b45e1cd0a38cf4836133762881920c4199dba2ba7d8a8fe1f3
(dev) [zaki@cloud-dev image]$ docker create --name=ceos-4-23 --privileged -p 22443:443 -e CEOS=1 -e container=docker -e EOS_PLATFORM=ceoslab -e SKIP_ZEROTOUCH_BARRIER_IN_SYSDBINIT=1 -e ETBA=1 -e INTFTYPE=eth -i -t ceos:4.23.4.2M /sbin/init
e98a20504882be7be9c57e53b4bed5a8b6da3903e76c7ae5d0cc12c511b1c12f
(dev) [zaki@cloud-dev image]$ docker start ceos-4-23
ceos-4-23
(dev) [zaki@cloud-dev image]$ docker exec -it ceos-4-23 sh
sh-4.2# Cl
CliCtrl              CliRelay             CliRelaySwitchAgent  CliShell             CloudHa      

あーなるほど、4.23以降だとCliコマンドがないんだな。


runせずにdocker createでコンテナを作成できるの知らなかったw (いつもrunしか使ってなかった)

[kubectl] kubectxとfzfでコンテキスト切り替えをインタラクティブに行う

コンテキストなどの切り替えが楽になるやつ。
職場の環境は切り替えが大量に発生するので使ってるけど、個人環境では使ってなかったので入れておいた。

kubectx, kubens

引数にコンテキスト名・ネームスペース名を指定するだけで切り替わるコマンド。

github.com

インストール

$ curl -LO https://github.com/ahmetb/kubectx/releases/download/v0.9.1/kubectx_v0.9.1_linux_x86_64.tar.gz
$ curl -LO https://github.com/ahmetb/kubectx/releases/download/v0.9.1/kubens_v0.9.1_linux_x86_64.tar.gz

自分の環境では/usr/local/binへ配置。

$ sudo tar xf kubectx_v0.9.1_linux_x86_64.tar.gz -C /usr/local/bin/ kubectx
$ sudo tar xf kubens_v0.9.1_linux_x86_64.tar.gz -C /usr/local/bin/ kubens

確認

$ kubectx --version
error: unsupported option '--version'
$ kubectx --version
error: failed to switch context: no context exists with the name: "version"
$ kubectx --help
USAGE:
  kubectx                       : list the contexts
  kubectx <NAME>                : switch to context <NAME>
  kubectx -                     : switch to the previous context
  kubectx -c, --current         : show the current context name
  kubectx <NEW_NAME>=<NAME>     : rename context <NAME> to <NEW_NAME>
  kubectx <NEW_NAME>=.          : rename current-context to <NEW_NAME>
  kubectx -u, --unset           : unset the current context  
  kubectx -d <NAME> [<NAME...>] : delete context <NAME> ('.' for current-context)
                                  (this command won't delete the user/cluster entry
                                   referenced by the context entry)
  kubectx -h,--help             : show this message
[zaki@cloud-dev bin]$ kubens --help
USAGE:
  kubens                    : list the namespaces in the current context
  kubens <NAME>             : change the active namespace of current context
  kubens -                  : switch to the previous namespace in this context
  kubens -c, --current      : show the current namespace
  kubens -h,--help          : show this message

バージョン確認はなかった。

コンテキスト確認

f:id:zaki-hmkc:20200919111915p:plain

だいたいこれと一緒。

$ kubectl config get-contexts -o name
context-c2daobwhbsg
kind-multi-1.15
kind-multicluster
kubernetes-admin@kubernetes
$ kubectl config get-contexts
CURRENT   NAME                          CLUSTER               AUTHINFO            NAMESPACE
*         context-c2daobwhbsg           cluster-c2daobwhbsg   user-c2daobwhbsg    
          kind-multi-1.15               kind-multi-1.15       kind-multi-1.15     
          kind-multicluster             kind-multicluster     kind-multicluster   
          kubernetes-admin@kubernetes   kubernetes            kubernetes-admin    

コンテキスト切り替え

f:id:zaki-hmkc:20200919112004p:plain

before

$ kubectl config current-context
context-c2daobwhbsg

切り替え

$ kubectx kind-multicluster
✔ Switched to context "kind-multicluster".

after

$ kubectl config current-context
kind-multicluster

だいたいこれと一緒。

$ kc config use-context kind-multicluster 
Switched to context "kind-multicluster".

zaki-hmkc.hatenablog.com

fzf

これだけだとkubectl config use-context <context-name>と(タイプ数が違う程度で)さほど変わらないけれど、fzfを併用することで、インタラクティブにコンテキストやネームスペースを切り替えできるようになる。

github.com

CentOS(yum)用はリポジトリなさげ。「Using git」でインストールする。

$ git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
$ ~/.fzf/install

実行例

[zaki@cloud-dev ~]$ ~/.fzf/install
Downloading bin/fzf ...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   650  100   650    0     0   1275      0 --:--:-- --:--:-- --:--:--  1277
100 1133k  100 1133k    0     0   437k      0  0:00:02  0:00:02 --:--:--  580k
  - Checking fzf executable ... 0.22.0
Do you want to enable fuzzy auto-completion? ([y]/n) y
Do you want to enable key bindings? ([y]/n) y

Generate /home/zaki/.fzf.bash ... OK
Generate /home/zaki/.fzf.zsh ... OK

Do you want to update your shell configuration files? ([y]/n) y

Update /home/zaki/.bashrc:
  - [ -f ~/.fzf.bash ] && source ~/.fzf.bash
    + Added

Update /home/zaki/.zshrc:
  - [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
    + Added

Finished. Restart your shell or reload config file.
   source ~/.bashrc  # bash
   source ~/.zshrc   # zsh

Use uninstall script to remove fzf.

For more information, see: https://github.com/junegunn/fzf

これで~/.bashrcには

[ -f ~/.fzf.bash ] && source ~/.fzf.bash

が追記される。

これで新しいシェルを起動するか、sourceで内容を取り込めば、

$ kubectx

の実行が「現在値の出力」だったのが「リストから上下キーで選択・文字入力でインクリメンタルサーチ・Enterで変更」という動作に拡張される。

実行時のインタラクティブな画面など詳しくはこちら

alias例

kubectlkcで運用してるので、kubectxkxkubensknにしてる。

alias kc=kubectl
source <(kubectl completion bash)
complete -o default -F __start_kubectl kc

alias kx=kubectx
alias kn=kubens

[ESXi / CentOS 7] ディスクを"追加"してパーティションサイズを拡張

実はスナップショットがあると既存ディスクのサイズ拡張ができなかったので、新しくディスクを作成してパーティションサイズを拡張した。

zaki-hmkc.hatenablog.com

内容は、上記の「サイズ拡張した領域にパーティション作成して拡張」が「新しく追加したディスクにパーティション作成して拡張」になったので、手順は同じ。
環境は、ESXiは6.5、VMのOSはCent OS 7

VMにディスクを追加

ESXiでディスクを新規作成して追加する。(通常の手順)

f:id:zaki-hmkc:20200915222035p:plain

VMを起動

[zaki@manager-dev ~]$ df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
devtmpfs                  1.9G     0  1.9G    0% /dev
tmpfs                     1.9G     0  1.9G    0% /dev/shm
tmpfs                     1.9G   12M  1.9G    1% /run
tmpfs                     1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/mapper/centos-root    16G  9.6G  6.0G   62% /
/dev/sda1                1014M  292M  723M   29% /boot
tmpfs                     378M     0  378M    0% /run/user/1000

バイス確認

[zaki@manager-dev ~]$ sudo fdisk -l

Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x0009f820

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    41943039    19921920   8e  Linux LVM

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト

パーティションが何もない/dev/sdbが新しいディスク。

パーティション作成

[zaki@manager-dev ~]$ sudo fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x804cc948.

コマンド (m でヘルプ): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x804cc948

デバイス ブート      始点        終点     ブロック   Id  システム

コマンド (m でヘルプ): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
パーティション番号 (1-4, default 1):
最初 sector (2048-41943039, 初期値 2048):
初期値 2048 を使います
Last sector, +sectors or +size{K,M,G} (2048-41943039, 初期値 41943039):
初期値 41943039 を使います
Partition 1 of type Linux and of size 20 GiB is set

コマンド (m でヘルプ): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x804cc948

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdb1            2048    41943039    20970496   83  Linux

コマンド (m でヘルプ):

typeをLinux LVMに

コマンド (m でヘルプ): t
Selected partition 1
Hex code (type L to list all codes): L

 0  空              24  NEC DOS         81  Minix / 古い Li bf  Solaris
 1  FAT12           27  Hidden NTFS Win 82  Linux スワップ  c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 隠し C: ド c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux 拡張領域  c7  Syrinx
 5  拡張領域        41  PPC PReP Boot   86  NTFS ボリューム da  非 FS データ
 6  FAT16           42  SFS             87  NTFS ボリューム db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux プレーン  de  Dell ユーティリ
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt
 9  AIX ブート可能  4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access
 a  OS/2 ブートマネ 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad ハ eb  BeOS fs
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         ee  GPT
 f  W95 拡張領域 (L 54  OnTrackDM6      a6  OpenBSD         ef  EFI (FAT-12/16/
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        f0  Linux/PA-RISC
11  隠し FAT12      56  Golden Bow      a8  Darwin UFS      f1  SpeedStor
12  Compaq 診断     5c  Priam Edisk     a9  NetBSD          f4  SpeedStor
14  隠し FAT16 <32M 61  SpeedStor       ab  Darwin ブート   f2  DOS セカンダリ
16  隠し FAT16      63  GNU HURD または af  HFS / HFS+      fb  VMware VMFS
17  隠し HPFS/NTFS  64  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE
18  AST SmartSleep  65  Novell Netware  b8  BSDI スワップ   fd  Linux raid 自動
1b  隠し W95 FAT32  70  DiskSecure Mult bb  隠し Boot Wizar fe  LANstep
1c  隠し W95 FAT32  75  PC/IX           be  Solaris ブート  ff  BBT
1e  隠し W95 FAT16  80  古い Minix
Hex code (type L to list all codes): 8e
Changed type of partition 'Linux' to 'Linux LVM'

コマンド (m でヘルプ): p

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
Disk label type: dos
ディスク識別子: 0x804cc948

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdb1            2048    41943039    20970496   8e  Linux LVM

コマンド (m でヘルプ):
コマンド (m でヘルプ): w
パーティションテーブルは変更されました!

ioctl() を呼び出してパーティションテーブルを再読込みします。
ディスクを同期しています。
[zaki@manager-dev ~]$

PV作成

[zaki@manager-dev ~]$ sudo pvcreate /dev/sdb1
  Physical volume "/dev/sdb1" successfully created.
[zaki@manager-dev ~]$ sudo pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               centos
  PV Size               <19.00 GiB / not usable 3.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              4863
  Free PE               0
  Allocated PE          4863
  PV UUID               b4agB4-x8BO-5S1d-TBqO-eAy5-j1Oh-esCLH0

  "/dev/sdb1" is a new physical volume of "<20.00 GiB"
  --- NEW Physical volume ---
  PV Name               /dev/sdb1
  VG Name
  PV Size               <20.00 GiB
  Allocatable           NO
  PE Size               0
  Total PE              0
  Free PE               0
  Allocated PE          0
  PV UUID               HZOcQv-sADc-9hGs-a82C-sCBF-iV8y-4fCzbQ

[zaki@manager-dev ~]$

/dev/sdb1が作成された。

VGに割り当て

既存のVG Name: centosに割り当てる。

[zaki@manager-dev ~]$ sudo vgextend centos /dev/sdb1
  Volume group "centos" successfully extended
[zaki@manager-dev ~]$
[zaki@manager-dev ~]$
[zaki@manager-dev ~]$ sudo pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda2
  VG Name               centos
  PV Size               <19.00 GiB / not usable 3.00 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              4863
  Free PE               0
  Allocated PE          4863
  PV UUID               b4agB4-x8BO-5S1d-TBqO-eAy5-j1Oh-esCLH0

  --- Physical volume ---
  PV Name               /dev/sdb1
  VG Name               centos
  PV Size               <20.00 GiB / not usable 3.00 MiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              5119
  Free PE               5119
  Allocated PE          0
  PV UUID               HZOcQv-sADc-9hGs-a82C-sCBF-iV8y-4fCzbQ

LVに割り当て

[zaki@manager-dev ~]$ sudo lvdisplay
  --- Logical volume ---
  LV Path                /dev/centos/swap
  LV Name                swap
  VG Name                centos
  LV UUID                Hjx34Z-CG7J-cKUz-C1xw-0UGo-TzWU-kD1OIG
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2020-01-18 20:23:50 +0900
  LV Status              available
  # open                 2
  LV Size                3.50 GiB
  Current LE             896
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:1

  --- Logical volume ---
  LV Path                /dev/centos/root
  LV Name                root
  VG Name                centos
  LV UUID                8RekUb-5l0N-3doV-hhNJ-6Tdw-kaTU-VDcYnS
  LV Write Access        read/write
  LV Creation host, time localhost.localdomain, 2020-01-18 20:23:50 +0900
  LV Status              available
  # open                 1
  LV Size                <15.50 GiB
  Current LE             3967
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     8192
  Block device           253:0

[zaki@manager-dev ~]$

LV Path: /dev/centos/rootを拡張する

[zaki@manager-dev ~]$ sudo lvextend -l +100%FREE /dev/centos/root
  Size of logical volume centos/root changed from <15.50 GiB (3967 extents) to 35.49 GiB (9086 extents).
  Logical volume centos/root successfully resized.

パーティションを拡張

[zaki@manager-dev ~]$
[zaki@manager-dev ~]$ sudo xfs_growfs /dev/centos/root
meta-data=/dev/mapper/centos-root isize=512    agcount=4, agsize=1015552 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=4062208, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 4062208 to 9304064
[zaki@manager-dev ~]$
[zaki@manager-dev ~]$
[zaki@manager-dev ~]$ df -h
ファイルシス            サイズ  使用  残り 使用% マウント位置
devtmpfs                  1.9G     0  1.9G    0% /dev
tmpfs                     1.9G     0  1.9G    0% /dev/shm
tmpfs                     1.9G   12M  1.9G    1% /run
tmpfs                     1.9G     0  1.9G    0% /sys/fs/cgroup
/dev/mapper/centos-root    36G  9.6G   26G   27% /
/dev/sda1                1014M  292M  723M   29% /boot
tmpfs                     378M     0  378M    0% /run/user/1000

これで20GBのディスク2つで、一つの40GBのパーティションとなった。
たぶんこっちの方が正しいやり方なんだろうな。。


参考サイト

前回と同じく、CentOS7 LVM を使ってディスクを拡張する | りんか ネット さんより。

(参考)ディスクサイズ拡張失敗の内容

f:id:zaki-hmkc:20200915222110p:plain

ちなみに、スナップショットがある(正確には不明。調査した限りでの切り分けポイントがスナップショットの有無だった)と、以下のエラーでディスクサイズの変更(拡張)に失敗するけど詳細がよくわからなかった。

Reconfig VM

項目
キー haTask-106-vim.VirtualMachine.reconfigure-170623095
説明 この仮想マシンを再設定します。
仮想マシン cloud-dev
状態 失敗 - デバイス「2」では無効な操作です。
エラー