dockerまわり全く使いこなせていない初心者です。とりあえずできたとこだけ書く体で失礼します。
最近Azureのまわしものみたいになってるのでなんとなく言い訳しますが個人的には他意は特に無くて使えれば何でもいいです。
目的と経緯など
勉強がてらやってみろということだったのでrancherでgitlabとか動かすくらいで済む予定だったのですがprometheusって言われたのでそれもやろうとして、
prometheusの立て方や連携方法は色々あってrancherのカタログからポチでもgrafanaと連携されてるものが上がってくるのですがalertmanagerの機能が必要な割にそのカタログには組み込まれておらず、カタログの自作とカスタマイズの方法が若干やってみた程度では全く成功せず解決方法がさっぱりわからなかったしそのカタログは設定ファイル自体のコンテナビルド的な私には理解不能(ビルドしないで設定更新したくないです?どうして?)な構成だったのでkubernetesでhelmつかうのがhelmのstableのポリシー見た感じよさそうかもしれないと思った次第。
で、AzureFileを永続ボリュームにするのは成功したんですが、
helmクライアントがhttpsのnginx-proxyの裏のtillerサーバに到達できない?
みたいでhelmでkubernetesクラスタを操ることができない状況だったけど
RancherのGUIのkubectl用CLIの画面からhelm init;helm repo update
とかするとhelm実行できた
すぐセッションきれてリロードしないと繋げないけど毎回initしなけいけないわけじゃないからいいかな ←イマココ
(ELBの人はリスナープロトコルをHTTPSからSSLにしたらアッサリ解決とか書いてた)
たすけてドラえも~ん!!といえる相手がこれに関してはあんまり周りにいないので追ってふつうにyamlのマニフェスト書くしかないのかrancherで動かすのやめて自前ビルド(単純に難しそう)かマネージドサービスが楽そうかなー(たぶん勉強がてらなのでマネージドは許されない気がする)とか思ってるとこです。
それはともかくkubnernetesのPVとPVCをAzureFileでやってみてる人少なそうだったので書いときます。
ちなみにRancherからはnfsはできるけどcifs・samba(azurefile)はストレージドライバとして使えるようには1.6時点でなってない模様(検索してたらPRは見かけた気がする)
kubernetesの用語備忘録など
WEB+DBのvol99が良いということで運よく会社にあったのを拝借してちょっと読んでみたその解説によるととりあえず座学っぽいとこは以下のような感じでした。(あとkubernetesは綴りが長いせいかk8sて書いてる人おおいのでそれが略称の模様)
- Podは同一ノードで動くコンテナのセットでPodごとにIPが振られる。apiとwebやリバプロとwebを一緒にしとく
- Labelをはっとくと検索して同じラベルのリソースがグルーピングされてそれに同じ処理をするとかできる
- Serviceは複数のpodがぶら下がった外部からのアクセスを制御するエンドポイントでいくつかの種類がある (ClusterIPはDNS、NodePortはポートマッピング、LoadbalancerはIngress、ExternalNameはCNAMEレコード、HeadlessはStatefulsetにつかう内部DNSっぽいのという理解)
- IngressはpodへのアクセスをHTTPプロキシするやつでTLSもいけるらしい
- Volumeはデータの格納領域で幾つか種類があるが複数ノードからのアクセスを可能にしておく永続的なものが推奨される (emptyDirVolumeはホストの領域をつかうがPodが削除されると消える、hostPathVolumeはホストのマウントパスを明示的に指定するがホストが消えると消えてしまう
- PersistentVolume(PV)を作っといてPersistentVolumeClaim(PVC)でPVリソースからどれだけ利用するかを指定する。(そうするとデータの永続化ができる、PVとPVCは1対1の紐づけのみ) 動的なプロビジョニングの場合にはStorageClassという仕組みを利用してプロビジョニングをする。StorageClass名をPVC側で指定するとよきようにマッピングしてくれる
- ConfigMap/Secretで設定をコンテナイメージから切り離す。それをつかうにはVolumeとしてマウントするか環境変数に設定するなどの方法がある
- podそのものは自分の状態を管理することができないので各コントローラというリソースを用いる
- ReplicaSetは水平スケーリング用のコントローラで複数の同一の内容のpodをいくつつくるかを管理する
- DeploymentはイメージをBGデプロイしてデフォルト1世代のこしといて切り戻しができるコントローラ
- HorizontalPodAutoscalingによる自動水平スケーリングではCPU負荷(2017/7月時点)の増減により処理を行う
- DaemonSetは各ノードに1コンテナずつ配置するコントローラでFluentdやPrometheusのNodeExporterなどが例としてある
- Statefulsetはその名の通りデータ持ってるやつでIDが順繰り振られてその順に起動するので0をマスタにするDBコンテナに適してる。削除後に同じIDのpodが起動するし全く同じボリュームが割り当たる
- Job/CronJobはタスクの実行を行うものでPodからの成功通知を待って終了するのとparallismの数だけpodが作成される
AzureFileを準備
ストレージアカウントを作りアカウント名とKeyを控えてAzureFileのコンテナを作成する必要があります。
ポータルからポチポチでもazコマンドでもググるといいしポータルのUIはわかりやすいのでググらなくてもどうとでもなると思うので準備が必要という点だけ書いておきます。
Secretを登録する
先にストレージアカウント情報をSecretに登録しておきます。
# mkdir /home/docker/k8s;cd /home/docker/k8s
# echo -n 'ストレージアカウントのKEY' > azstorage-secret.txt
# kubectl create secret generic azstorage-secrets \
--from-file=azurestorageaccountkey=azstorage-secret.txt \
--from-literal=azurestorageaccountname=${mystrageaccount}
なぜかbase64で文字列を暗号化してからyamlに書いてそれを登録という方法だとうまくいかなかったんですが、たぶんストレージアカウント名も暗号化しないといけなかったんだなとできたほうの出力を見て思いました(確かめてはいない)
createするときに--namespace monitor
とかつけとくとnamespace分けられるのでCLIやダッシュボードの表示が見やすくなったりなどしますが指定しないとdefaultで後からだとsecretから登録しなおす感じでした。リポジトリ単位で分けるとよいとか見た気がします。
Kubernetes の各リソースに対するメモ - Qiita
登録されたことを確認
# kubectl get secrets azstorage-secrets -o yaml
apiVersion: v1
data:
azurestorageaccountkey: ***********L3c9PQ==
azurestorageaccountname: *****hdGlvbg==
kind: Secret
metadata:
creationTimestamp: 2017-12-08T07:09:02Z
name: azstorage-secrets
namespace: default
resourceVersion: "8462"
selfLink: /api/v1/namespaces/default/secrets/azstorage-secrets
uid: abd5529c-dbe6-11e7-9680-02de519233a2
type: Opaque
k8sのダッシュボードを見てみるとシークレットが増えてました。
azureのストレージアカウント情報登録した瞬間にvolumeに指定すればPodからマウントできるっぽいようにPodのyaml書いてる人いました。
wordpressの例とかもあった
ここにあるストレージの一覧をみるとReadWriteManyにAzureFileが入ってて複数ノードからの読み書きができるという話。
AzureFileのノード上でのmountコマンドの戻り値みたときrsize=1048576,wsize=1048576とかだった。
PersistentVolume(PV)をつくる
永続ボリュームを以下のようにAzureFileで作ってみます。nfsのやり方はここらへんで見かけました
# vi azfile-pv.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
name: pv001
spec:
capacity:
storage: 1024Gi
accessModes:
- ReadWriteMany
azureFile:
secretName: azstorage-secrets
shareName: k8s-data
readOnly: false
# kubectl create -f azfile-pv.yaml
persistentvolume "pv001" created
ハイフン3つで区切ってPVCも一緒に書いて作っても大丈夫です。
注意点としてaccessModesはPVとPVCでの両方で一致してないとPVC作ったときにステータスがPendingのままで使えないしダッシュボードにも表示されないです。
複数ボリュームがある場合にPVにlabelをつけとくとPVCからselector指定して明示的にできる模様
label/selectorはこのほかにもルーティング等いろいろ使う模様。
PVとPVCは1対1の紐づけのみ。
PersistentVolumeClaim(PVC)をつくる
永続ボリューム要求は用語のところで書いてるとおり、永続ボリュームに対するリクエスト。これをPodのyamlにvolumesとして指定します。
# vi azfile-pvc.yml
# cat azfile-pvc.yml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: azfileclaim01
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
selector:
matchLabels:
name: pv001
# kubectl create -f azfile-pvc.yml
persistentvolumeclaim "azfileclaim01" created
storageclassをつくってみる
なんかダッシュボードにワーニングが出てたので一応作ってみた次第(PV作る時には指定してもしなくても大丈夫でPVCに指定すると自動で割り当てたいときにいいらしい)
# vi azstorageclass.yml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
skuName: Standard_LRS
location: japanwest
storageAccount: mystorageaccount
# kubectl create -f azstorageclass.yml
storageclass "azurefile" created
pvやpvcに書くときはstorageClassName: azurefile
という行を追加する感じの模様
CLI、ダッシュボードから確認
# kubectl get persistentvolumeclaims
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
azfileclaim01 Bound pv001 1Ti RWX 6s
# kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nfs 20Gi RWX Retain Bound default/nfsclaim01 1d
pv001 1Ti RWX Retain Bound default/azfileclaim01 7d
PVCを使いPodを立ててみて更新データがAuzreFileからみられることを確認する
# vi /opt/rc-azfile.yml
kind: Pod
apiVersion: v1
metadata:
name: rc-azfile-test
labels:
app: nginx
spec:
volumes:
- name: azurefile
persistentVolumeClaim:
claimName: azfileclaim01
containers:
- name: nginx
image: nginx
ports:
- name: nginx
containerPort: 80
volumeMounts:
- name: azurefile
mountPath: "/usr/share/nginx/html"
# kubectl create -f /opt/rc-azfile.yml
pod "rc-azfile-test" created
# kubectl get pods
NAME READY STATUS RESTARTS AGE
rc-azfile-test 1/1 Running 0 45m
k8sかrancherダッシュボードまたはdockerコマンドでもなんでもいいのでコンテナに入ってdfでもみてみるとなんかマウントできてるのが見えます
root@rc-azfile-test:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@rc-azfile-test:/# df -h
Filesystem Size Used Avail Use% Mounted on
none 30G 4.0G 26G 14% /
tmpfs 1.7G 0 1.7G 0% /dev
tmpfs 1.7G 0 1.7G 0% /sys/fs/cgroup
/dev/sda1 30G 4.0G 26G 14% /etc/hosts
shm 64M 0 64M 0% /dev/shm
//mystorageaccount.file.core.windows.net/k8s-data 1.0T 64K 1.0T 1% /usr/share/nginx/html ←★これ
tmpfs 1.7G 12K 1.7G 1% /run/secrets/kubernetes.io/serviceaccount
ここでなんかファイル作るとAzureFileのポータル画面からもダウンロード可能に。
サブディレクトリ切ったほうが良かったですね。
helmが便利そうだなと思った件
失敗してるのが超残念なんですがhelmのstableはわりと便利そうだなあと思った次第。
・データ永続化の方法が提供される
・アプリケーションのアップグレードがサポートされる
・アプリケーション設定のカスタマイズを許可する
・セキュアなデフォルト設定を持つ
・Kubernetesのアルファ機能を利用しない
ということだそうでつかいやすそう。
もしhelmが使えてたら以下のようなコマンドを実行してみたかった。一時的にhttpsやめて切り分けてみてもいいかな。
以下例。アクセスモードが一致するPV,PVCが用意されてないとexporterとかは上がってくるけどPrometheusとalertmanagerのサーバが起動しないので一致するアクセスモードのPersistentVolumeとPersistentVolumeClaimを用意しないといけなかったりします。prometheus側のPVCはエラー検索したらどうやらファイル共有がロックの仕組み的にNGっぽいIssueを見かけました。なのでhost_path的な何かでやるしかなさげ。helm statusでも稼働してる数とかみると状況はわかるけどkubernetes側のダッシュボードで赤くなってるしエラーメッセージがわかりやすいです。あと個人的にはrancherの方が過去ログを追いやすい気がしました。
> helm install stable/prometheus --name monitor --namespace monitor --set \
> persistence.enabled=true,alertmanager.persistentVolume.existingClaim=alertmanager-claim-rwm,alertmanager.persistentVolume.accessModes=ReadWriteMany,server.persistentVolume.existingClaim=prom-pv-claim,server.persistentVolume.accessModes=ReadWriteOnce
ちなみにhostpathのpvとpvcは以下のような感じでよいようでした。hostpathはコンテナからホストにマウントされるのでホストがお陀仏するまでは大丈夫で1ホストからしかアクセスできないやつですね。昨今はホストも使い捨てだし形あるものは必ず壊れるのでデータのバックアップは要りそうですね。
# cat prom-hostpath-pv*
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prom-pv-claim
namespace: monitor
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: prom-hostpath-pv
labels:
type: local
namespace: monitor
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /var/lib/prometheus
# type: DirectoryOrCreate
# kubectl create -f prom-hostpath-pv.yml
# kubectl create -f prom-hostpath-pvc.yml
# kubectl --namespace=monitor get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv/prom-hostpath-pv 5Gi RWO Retain Bound monitor/prom-pv-claim 35m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc/prom-pv-claim Bound prom-hostpath-pv 5Gi RWO 35m
RancherのGUIのkubectl用CLI以外のノードから実行だと以下のようなエラーでるのは変わらないですね。解決方法をご存知の方がいらしたらおしえてください。ぜひ!
# helm version --debug
[debug] Created tunnel using local port: '38139'
[debug] SERVER: "127.0.0.1:38139"
Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
E1215 22:59:36.901993 31974 portforward.go:271] error creating error stream for port 38139 -> 44134: Timeout occured
[debug] rpc error: code = Internal desc = transport is closing
Error: cannot connect to Tiller
# kubectl -n kube-system get po
NAME READY STATUS RESTARTS AGE
heapster-76b8cd7b5-7qvbl 1/1 Running 0 7d
kube-dns-5d7b4487c9-4wzsn 3/3 Running 0 7d
kubernetes-dashboard-5ffb9c9bb7-9jczl 1/1 Running 0 7d
monitoring-grafana-997796fcf-wpwtr 1/1 Running 0 7d
monitoring-influxdb-56fdcd96b-k85vt 1/1 Running 0 7d
tiller-deploy-79c88c5d98-n7qgm 1/1 Running 0 7d
なお、PrometheusとAlertmanagerカタログから起動とサービス追加して若干触ったのと調べてた限りgrafanaでの表示はとてもきれいだったのと既成メトリクスとexporterが多いとこはいいし通知まとめられるのいいけど設定がyamlのみでGUIがないようだと監視オペレータ連携運用が事実上難しくそこそこ工数かかるエンジニアの人手がいる運用になりそうな予感しかないです。
rancherの環境をkubernetesにして起動した場合の気づいたことなど
・アクセスコントロールの設定をしてる場合、rancher側でログイン認証しないとログアウト状態でkubernetesのダッシュボードを操作することができない(認証連携されてた)
・初回起動時に環境をkubernetesに切り替えてからホスト登録しないとだめっぽい。
既存のクラスタにrancherのkubernetesの環境からノードついかするとkubernetesのダッシュボードにも表示される
・kubernetesクラスタのmasterとかnodeとかそういうロールについては起動しただけだと定義されてないっぽい
・rancher2.0はpreviewで認証機能が無効なので真面目に使うとすると手前のnginx的なリバースプロキシに何か認証機能を持たせるとかしないとだめそう。AzureADだとnginx自前ビルドでsub_filterモジュール有効化してどうこうしないとという地雷臭がする感じ。
・rancherのほうがUIが見やすいきがするがkubernetesのダッシュボードでもrancherでできることは大体できる気がする(別に両方使いこなせてないですがコンテナにつなぐとかログ見るくらいのことはどっちもできる)
・kubernetesのダッシュボードは手動更新がほとんどできなくて主にkubectlとyamlで色々やる体でrancherは画面からポチポチしてあとでyaml確認して取っとくみたいな違いがあるかなあと思いました。先か後かは別としてどっちもまあ見える化に配慮しているのかなと思いました。
参考
・kubenetes関連
Azureコンテナサービス:Azureファイルストレージを永続的な(kubernetes)ボリュームとして使用する - Karim Vaes
Docker と Kubernetes を使って『変化に強いインフラ』を作る | Wantedly Engineer Blog
RancherでKubernetesでHelmでDockerでJenkinsを動かす方法 - Qiita
Configure a Pod to Use a PersistentVolume for Storage | Kubernetes
永続的なボリューム| Kubernetes
kubernetes入門コンテンツまとめ - Qiita
第2回 Kubernetesの歩き方
Kubernetesに入門したい // Speaker Deck
Kubernetesクラスタ環境を構築してDashboardで見える化を試してみた - Taste of Tech Topics
トラブルシューティング | Kubernetes Engine ドキュメント | Google Cloud Platform
https://qiita.com/apstndb/items/9d13230c666db80e74d0
Kubernetes ときどき Serverless -- cndjp第1回勉強会
Kubernetes in プロダクション! -- cndjp第2回
【IBM Cloud k8s検証メモ】二つ以上の永続ストレージを識別してマウント - Qiita
・helm関連
Kubernetes: パッケージマネージャHelm - Qiita
Helm を使用して Azure Kubernetes にコンテナーをデプロイする | Microsoft Docs
helm/install.md at master · kubernetes/helm
charts/stable/prometheus at master・kubernetes / charts
Ladicle/kubernetes-helm-jp-doc: Kubernetes helm Japanese document
Kubernetes Addons in Rancher
・prometheus関連
prometheus で雑に始めるサーバ監視 - Qiita
Alertmanagerについて書いてみる - wyukawa’s blog
Exporters and integrations | Prometheus
Monitoring at AbemaTV - SSSSLIDE
AbemaTVにPrometheusというモニタリングシステムを導入した話