事情によりやってみた備忘録です。
(AKSじゃないのかよというツッコミは甘んじてうけます)
これから新規ならAKSがいいかとおもいます。
https://docs.microsoft.com/ja-jp/azure/aks/acs-aks-migration
ACSたてる
・目的のサブスクリプションなことを確認
az account list
az account show
・違ってたらset
az account set --subscription xxxx-xxxx....
・リソースグループ作る
# az group create --name $my_resouce_grp --location japaneast
・ACSクラスタつくる
# az acs create --orchestrator-type kubernetes --resource-group $my_resouce_grp --name $my-acs-cluster --generate-ssh-keys
SSH key files '/root/.ssh/id_rsa' and '/root/.ssh/id_rsa.pub' have been generated under ~/.ssh to allow SSH access to the VM. If using machines without permanent storage like Azure Cloud Shell without an attached file share, back up your keys to a safe location
標準出力の戻り値にマスタサーバへのsshコマンドがあるので必要ならそれで乗り込むとkubectlがなにもしなくても入っていてクラスタへのクレデンシャルが配置されている。
この時点でダッシュボードからノード数を変えられる
・クラスタに接続するための認証情報を設定ファイルにマージする
# az acs kubernetes get-credentials --resource-group $my_resouce_grp --name $my-acs-cluster
Merged "xxxx" as current context in /root/.kube/config
・kubectlを入れて使う
centos7ならyumで入るようでした(ACSクラスタはubuntsでできていた)
# yum install -y kubectl
# kubectl get nodes
# kubectl cluster-info
# kubectl get po,deploy,rs,svc,ds --all-namespaces
とくに何もしてないとkube-systemというnamespaceの情報がでてくる
Datadogエージェントを色々な入れ方でいれる
201807現在のdatadog-agentのメジャーバージョンは6になる。
VMの場合
・パッケージインストール(サインアップ画面で表示されるワンライナー)
DD_API_KEY=a04e9e02f5**************b37bd6a bash -c "$(curl -L https://raw.githubusercontent.com/DataDog/datadog-agent/master/cmd/agent/install_script.sh)"
対象:監視が必要なすべてのホストに。
・設定修正
$ cd /etc/datadog-agent/
$ cp -p datadog.yaml{,.org}
$ vi datadog.yaml
$ sudo diff datadog.yaml datadog.yaml.org
256c256
< config_providers:
---
> # config_providers:
260,261c260,261
< - name: kubelet
< polling: true
---
> # - name: kubelet
> # polling: true
505c505
< process_config:
---
> # process_config:
510c510
< enabled: "true"
---
> # enabled: "true"
$ sudo systemctl status datadog-agent
$ sudo systemctl restart datadog-agent
$ sudo systemctl status datadog-agent
プロセスが取得できるようにとkubeletのチェックができるように設定を実施。
(コンテナ内のプロセスまで見なくていいらしいけどVMでetcdが動いてるかどうか的なVM上のプロセスは見たい)
Azure統合の場合
・DatadogのIntegrationの設定画面で以下を登録する
サービスプリンシパルのクライアントIDとパスワード、AzureADのディレクトリのテナントのID
https://docs.datadoghq.com/integrations/azure/
https://docs.datadoghq.com/ja/integrations/azure/
※ResouceGroup限定できてないせいかサブスクリプションに含まれるホストが丸ごと出てくるという仕様な気がした
k8s統合の場合
ACSの環境のマニュアル
https://docs.microsoft.com/ja-jp/azure/container-service/kubernetes/
AKSのマニュアル
https://docs.microsoft.com/ja-jp/azure/aks/
k8sクラスタがある前提で話をすすめる。
helmチャートもあるのでそれでもいいかもしれないですがここでは普通にマニフェストで入れます。
公式そのままだとなんかマスタに入らなかったりしたのでtolerationsを追加した。
・まずAPIキーをSecretに登録する
$ echo -n "${DD_API_KEY}"|base64
$ vi secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
apikey: <ここにエンコードしたAPIKEYを記入>
$ kubectl create -f secret.yaml
secret "mysecret" created
$ kubectl get secret
$ kubectl describe secret mysecret
・変数をConfigmapに登録する
$ vi configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
namespace: default
data:
# キー名が環境変数名として展開される
KUBERNETES: "yes"
DD_COLLECT_KUBERNETES_EVENTS: "true"
DD_LEADER_ELECTION: "true"
DD_PROCESS_AGENT_ENABLED: "true"
DD_LOGS_ENABLED: "true"
DD_LOGS_CONFIG_CONTAINER_COLLECT_ALL: "true"
$ kubectl create -f configmap.yaml
configmap "myconfigmap" created
$ kubectl get configmap
NAME DATA AGE
myconfigmap 1 15m
$ kubectl describe configmap myconfigmap
・つぎに登録した値を読み込むdatadogのdaemonsetのマニフェストを用意する
$ vi datadog-agent.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: datadog-agent
spec:
# updateStrategy:
# type: RollingUpdate
# rollingUpdate:
# maxUnavailable: 1
# minReadySeconds: 10
template: ##Podのテンプレート
metadata:
labels:
app: datadog-agent
name: datadog-agent
spec:
containers:
- image: datadog/agent:latest
imagePullPolicy: Always
name: datadog-agent
ports:
- containerPort: 8125
name: dogstatsdport
protocol: UDP
- containerPort: 8126
name: traceport
protocol: TCP
envFrom: ##Configmapの変数を一括読み込み
- configMapRef:
name: myconfigmap
env: ##環境変数を定義(Secretをここで定義
- name: DD_API_KEY
valueFrom:
secretKeyRef:
name: mysecret
key: DD_API_KEY
## 以下があるとホストのhostnameコマンドの出力(本当のホスト名)ではなく、
## K8Sノード名(AWSの場合、ip-<private ip>)が使われてしまって、トレース、メトリクス、
## ログの#hostタグの値の整合がとれなくなってしまう
## https://github.com/DataDog/dd-agent/issues/3496#issuecomment-325642715
# - name: DD_KUBERNETES_KUBELET_HOST
# valueFrom:
# fieldRef:
# fieldPath: status.hostIP
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "256Mi"
cpu: "200m"
volumeMounts:
- name: dockersocket
mountPath: /var/run/docker.sock
- name: procdir
mountPath: /host/proc
readOnly: true
- name: cgroups
mountPath: /host/sys/fs/cgroup
readOnly: true
livenessProbe:
exec:
command:
- ./probe.sh
initialDelaySeconds: 15
periodSeconds: 5
tolerations: ##マスタに配置されるように定義
- key: node-role.kubernetes.io/master
operator: Equal
value: "true"
effect: NoSchedule
volumes:
- hostPath:
path: /var/run/docker.sock
name: dockersocket
- hostPath:
path: /proc
name: procdir
- hostPath:
path: /sys/fs/cgroup
name: cgroups
Daemonsetというのは、Podがホスト毎に1つずつ配置されるリソース。
Taintsがマスタに設定されておりそれに一致したtolerationsの指定をしていないと、
DaemonSetでもPodが配置されない、というスケジュールの仕組みになってるためtolerationsを設定。
(/etc/kubernetes/のしたのほうにあるkube-proxyのマニフェストにあるのと同じtolerations。)
https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
https://qiita.com/sheepland/items/8fedae15e157c102757f
・daemonsetでdatadogエージェントのPodを配置
$ kubectl create -f datadog-agent.yaml
$ kubectl get ds,po -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE-SELECTOR AGE CONTAINER(S) IMAGE(S) SELECTOR
ds/datadog-agent 3 3 3 3 3 <none> 1d datadog-agent datadog/agent:latest app=datadog-agent
NAME READY STATUS RESTARTS AGE IP NODE
po/datadog-agent-08056 1/1 Running 0 1d 10.244.2.10 k8s-agent-91c01bd8-1
po/datadog-agent-pbkcb 1/1 Running 0 1d 10.244.1.9 k8s-agent-91c01bd8-0
po/datadog-agent-w9dmb 1/1 Running 0 1d 10.244.3.6 k8s-master-91c01bd8-0
あとたぶんkube-state-metricsとかも入れたほうがいいのであとでたぶんhelmで入れなおす気がします。
Monitor登録とかも一応ためしていていつものVMのリソース・プロセス監視と外形監視とブラウザからポチポチ追加したり通知の文面にホスト変数やイベントIDやテキストなどの変数入れたりできて、
内容をExportしといてjsonにしといてそれをもとに流用してスクリプト組んでAPIで登録するというのもできてた。k8s的にはEventが大事らしいとかテンプレート毎のリソースの割り当てやノード側の制限方法やPod毎のデザインされた数と落ちて大丈夫な数の指定やLivenessProbeなどなどあるようでEvent監視はSyncloopBackoffほか登録したけども次回のcndjpでそのへんわかる気がするしkube-state-metricsいれるとタグでdeployment指定とかできるような記事をどこかでみたような(これからためします)。
mysqlをVM(Ubuntu)にふつうにシングルで入れる
InnoDBクラスタとかmysql-operatorとかStatefulSetでもよかったけどそちらに夢中になってしまうとアレなのでシンプルに。
(あとで外部サービスとしてのEndpointとServiceオブジェクト作ってアクセスさせる)
yumだとここのあたりだけども
https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/
Ubuntuなのでこのあたりで。(はじめてUbuntuにMySQLをいれた)
https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/
https://websiteforstudents.com/install-mysql-8-0-on-ubuntu-16-04-17-10-18-04/
マスタにわたるためのssh鍵でエージェントにも渡れる。
$ tail -3 /etc/hosts
10.240.0.6 k8s-agent-91C01BD8-nic-0 agent0
10.240.0.5 k8s-agent-91C01BD8-nic-1 agent1
10.240.255.5 k8s-master-91C01BD8-nic-0 master1
$ ssh agent0
なんとなくGIP確認
$ curl http://taruo.net/ip/?raw
cd /tmp/ && wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb
OKおす
sudo apt-get update
sudo apt-get install mysql-server mysql-client
The following additional packages will be installed:
libaio1 libmecab2 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-common
mysql-community-client mysql-community-client-core mysql-community-server
mysql-community-server-core
The following NEW packages will be installed:
libaio1 libmecab2 mecab-ipadic mecab-ipadic-utf8 mecab-utils mysql-client
mysql-common mysql-community-client mysql-community-client-core
mysql-community-server mysql-community-server-core mysql-server
0 upgraded, 12 newly installed, 0 to remove and 106 not upgraded.
Need to get 49.2 MB of archives.
After this operation, 403 MB of additional disk space will be used.
Do you want to continue? [Y/n]
# あと「強烈なパスワードの暗号化を使用する(推奨)」にOKおした(けどあとで設定なおした)
# (5.xと互換性がなくなるやつ)
$ sudo systemctl status mysql
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2018-07-13 07:27:26 UTC; 2min 15s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Main PID: 81202 (mysqld)
Status: "SERVER_OPERATING"
CGroup: /system.slice/mysql.service
└─81202 /usr/sbin/mysqld
起動している。
設定ファイル探した感じ以下のあたりにある
$ vi /etc/mysql/mysql.conf.d/mysqld.cnf
これをみたかんじ、上記がサーバ設定でconf.d/mysql.cnf
がクライアント用です。
http://jitsu102.hatenablog.com/entry/2018/05/06/191139
$ cat /etc/mysql/mysql.conf.d/mysqld.cnf
$ mysqld --verbose --help
$ mysqld --verbose --help --no-defaults
sudo cp -p /etc/mysql/mysql.conf.d/mysqld.cnf{,.org}
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
$ sudo diff /etc/mysql/mysql.conf.d/mysqld.cnf{,.org}
34,71d33
<
< # 旧 MySQL (5.7) との互換性確保
< default_authentication_plugin=mysql_native_password
<
< explicit_defaults_for_timestamp = true
<
< sql_mode = 'IGNORE_SPACE,PIPES_AS_CONCAT'
< server-id = 101
<
< log-bin-trust-function-creators=1
<
< character-set-server = utf8mb4
< collation-server = utf8mb4_ja_0900_as_cs
<
< # MySQL5.7の設定の互換性確保
< #character-set-server = utf8
< #collation-server = utf8_general_ci
< #init-connect = SET NAMES utf8
<
< #lower_case_table_names = 1
<
< # expire_logs_days = 1 <--- 次回から廃止の可能性あり
< binlog_expire_logs_seconds=18000
<
< slow_query_log=1
< long_query_time = 1.0
<
< max_connections = 300
< max_connect_errors = 10
<
< # transaction_isolation = READ-COMMITTED
<
< innodb_dedicated_server=ON
< innodb_lock_wait_timeout = 120
< # innodb_flush_log_at_trx_commit=0
<
< slave-skip-errors=1062,1032
<
$ sudo systemctl status mysql
$ sudo systemctl restart mysql
$ sudo systemctl status mysql
起動した。(parameterは適当です)
NWを介して接続可能でGrantOptionは持たないユーザを作成する
(phpmyadmin越しにユーザ作成は不可能になる)
GRANTのみによるユーザ作成はできなかったと思われる。
mysql -u root -p
CREATE USER user@'%' IDENTIFIED BY 'xxxxxx';
GRANT ALL ON *.* TO 'user'@'%';
show grants for user@'%';
FLUSH PRIVILEGES;
exit
この接続情報をphpmyadminでつかう。
phpmyadminをマニフェストでいれてみる
・secretにMySQLのパスワードを登録する
$ echo -n "axxxxxxx"|base64
YX*****aGc=
$ vi secret.yaml
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
MYSQL_PASSWORD: YXY1****aGc=
$ kubectl apply -f secret.yaml
・configmapにMySQLのパスワード以外の接続情報を登録する
$ vi configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
namespace: default
data:
# キー名が環境変数名として展開される
PMA_HOST: "external-ip-database.default.svc.cluster.local"
PMA_USER: user
PMA_PORTS: "3306"
PMA_ARBITRARY: "1"
PMA_VERBOSE: phpmyadmin
$ kubectl apply -f configmap.yaml
どんな変数が必要かはコンテナイメージのあるdocker_hubの解説を確認します。
https://hub.docker.com/r/phpmyadmin/phpmyadmin/
PMA_HOSTは次のyamlで作るDBのEndpointのServiceの名前。
service-name.namespace-name.svc.cluster.localが名前解決できてホストの指定に使える。
・本体のマニフェストを作成(Service、Deployment、Endpointを作成)
$ vi phpmyadmin.yaml
---
apiVersion: v1
kind: Service
metadata:
name: external-ip-database
spec:
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: v1
kind: Endpoints
apiVersion: v1
metadata:
name: external-ip-database
subsets:
- addresses:
- ip: 10.240.0.6
ports:
- port: 3306
---
apiVersion: v1
kind: Service
metadata:
name: phpmyadmin-front
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: phpmyadmin
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: phpmyadmin
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
run: phpmyadmin
spec:
containers:
- name: phpmyadmin
image: phpmyadmin/phpmyadmin
imagePullPolicy: Always
ports:
- containerPort: 80
## load PMA_HOST,PMA_USER,PMA_PORTS,PMA_ARBITRARY,PMA_VERBOSE
envFrom:
- configMapRef:
name: myconfigmap
env:
- name: PMA_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: MYSQL_PASSWORD
$ kubectl apply -f phpmyadmin.yaml
それぞれのリソースが疎結合(パーツ交換しやすい)だけど名前とlabelとセレクタなどでうっすら関係があるようになっているというかんじらしい。
phpmyadmin-frontend(Service) -> phpmyadmin(deployment) -> external-ip-database(Service) -> Endpoint(DBのIPアドレスを名前解決) -> vmに入れたmysql
yamlをapplyしたらそれぞれの状況を確認、
とくにLoadBalancerを指定したフロントのServiceに割り当たるExternalIPを確認して
それをブラウザで開いてphpmydaminの表示を確認する。
$ kubectl get po,svc,deploy,rc,ep,ds,cm,secret -o wide
NAME READY STATUS RESTARTS AGE IP NODE
po/datadog-agent-08056 1/1 Running 0 6d 10.244.2.10 k8s-agent-91c01bd8-1
po/datadog-agent-pbkcb 1/1 Running 0 6d 10.244.1.9 k8s-agent-91c01bd8-0
po/datadog-agent-w9dmb 1/1 Running 0 6d 10.244.3.6 k8s-master-91c01bd8-0
po/phpmyadmin-4033992027-b857p 1/1 Running 0 33m 10.244.2.16 k8s-agent-91c01bd8-1
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc/external-ip-database 10.0.187.44 <none> 3306/TCP 1h <none>
svc/kubernetes 10.0.0.1 <none> 443/TCP 11d <none>
svc/phpmyadmin-front 10.0.54.158 40.xxx.xxx.xxx 80:31464/TCP 4h app=phpmyadmin,run=phpmyadmin
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINER(S) IMAGE(S) SELECTOR
deploy/phpmyadmin 1 1 1 1 3h phpmyadmin phpmyadmin/phpmyadmin run=phpmyadmin
NAME ENDPOINTS AGE
ep/external-ip-database 10.240.0.6:3306 4h
ep/kubernetes 10.240.255.15:443 11d
ep/phpmyadmin-front 10.244.2.16:80 4h
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE-SELECTOR AGE CONTAINER(S) IMAGE(S) SELECTOR
ds/datadog-agent 3 3 3 3 3 <none> 6d datadog-agent datadog/agent:latest app=datadog-agent
NAME DATA AGE
cm/datadog-leader-election 0 6d
cm/myconfigmap 11 7d
NAME TYPE DATA AGE
secrets/default-token-twh7p kubernetes.io/service-account-token 3 11d
secrets/mysecret Opaque 2 7d
httpsと認証は別途という感じに。
Azureなのでアプリケーションゲートウェイを手前にかますことは可能な模様でした(LoadbalancerのIP指定して)
helmもあるようだったのでそちらの方が簡単かも(今回は意味と操作を理解するためにあえて書いた)
helmで仕組みが隠蔽されちゃうと理解しづらいし書いた人の一存で使いやすさが分かれるのでkustomizeがいいよみたいな話をみた気がします。(たぶんチャート書くレベルの人の話)
・podに入る方法と環境変数の確認方法と名前解決の確認方法
$ kubectl exec -it phpmyadmin-2566823841-7gwjd /bin/sh
# nslookup external-ip-database.default.svc.cluster.local
Name: external-ip-database.default.svc.cluster.local
Address 1: 10.0.187.44 external-ip-database.default.svc.cluster.local
# env
PHP_EXTRA_CONFIGURE_ARGS=--enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi
EXTERNAL_IP_DATABASE_SERVICE_PORT=3306
PHPMYADMIN_FRONT_PORT_80_TCP=tcp://10.0.54.158:80
KUBERNETES_PORT=tcp://10.0.0.1:443
KUBERNETES_SERVICE_PORT=443
EXTERNAL_IP_DATABASE_PORT=tcp://10.0.187.44:3306
PMA_PASSWORD=xxxxxxx
EXTERNAL_IP_DATABASE_PORT_3306_TCP=tcp://10.0.187.44:3306
URL=https://files.phpmyadmin.net/phpMyAdmin/4.8.2/phpMyAdmin-4.8.2-all-languages.tar.xz
PHP_INI_DIR=/usr/local/etc/php
~略~
コンテナはサイズ小さくしたい関係でコマンドが限られたものしか入ってないことが多くbashないことも。
あと、マニフェストのapiVersionとkubernetesのバージョンで許容する書き方が案外違っている感じだった。
いちおう、マイクロサービスの集合を扱うようなのが向いててそうでもない規模の場合にマスタと移行と学習のコストがという話は理解していて、ただマスタは無料みたいなPaaSが多いのと、イメージによる管理ができることで環境差分の管理が簡単になってテストをポータブルに簡単にできてVMかまさないから起動早いところがいいとかそういうことかなというところ。オートスケーリングとオートヒーリングを使いこなすとありがたみがわかりやすそう。あとステートフルなのは全然向いてなくてAPIの集合みたいなステートレスなシステム(PaaSみたいなのかな)が向いてるらしい。(コンテナで本番DB運用してる人をみない。PaaSのDBつかってる。)
https://qiita.com/komattaka/items/bd1d8d32f6cb24a32f53
https://qiita.com/MahoTakara/items/d18d8f9b36416353066c
https://qiita.com/MahoTakara/items/098a794c71f0ae2be429
https://hub.docker.com/r/phpmyadmin/phpmyadmin/
https://github.com/phpmyadmin/docker
https://github.com/kubernetes/charts/tree/master/stable/datadog
https://www.datadoghq.com/ja/blog/monitoring-kubernetes-datadog/#kubernetes-components
https://qiita.com/mumoshu/items/4c19695e5c9e3edd098b
https://thinkit.co.jp/article/13542
http://dr-asa.hatenablog.com/entry/2018/04/10/171807
https://knowledge.sakura.ad.jp/3681/
https://docs.microsoft.com/ja-jp/azure/aks/
https://qiita.com/superbrothers/items/650d6591aa6531bdbd08
https://qiita.com/cvusk/items/100dfb955150ef8964e5
https://codezine.jp/article/detail/10828
https://access.redhat.com/obsolete-documentation/ja/red-hat-enterprise-linux-atomic-host/7/paged/getting-started-with-containers/chapter-4-troubleshooting-kubernetes
https://github.com/oracle/mysql-operator/blob/master/docs/tutorial.md
http://dr-asa.hatenablog.com/entry/2017/12/19/095008
https://github.com/yoshioterada/k8s-Azure-Container-Service-AKS--on-Azure
https://kubernetes.io/docs/concepts/storage/persistent-volumes/