elasticsearch exited with code 137
でdockerコンテナが落ちるので調べていた。
デフォルトはいくつなんだろう? 私の場合2GBになっていたので、OOMで落ちていた。
ググったら下記にたどりついて、docker for mac自体のメモリLimitかと気づいた。 Container crashes with code 137 when given high load · Issue #22211 · moby/moby · GitHub
elasticsearch exited with code 137
でdockerコンテナが落ちるので調べていた。
デフォルトはいくつなんだろう? 私の場合2GBになっていたので、OOMで落ちていた。
ググったら下記にたどりついて、docker for mac自体のメモリLimitかと気づいた。 Container crashes with code 137 when given high load · Issue #22211 · moby/moby · GitHub
Amazon - Badge Verification - CertMetrics
Solutions Architect Associateの次に受けたAWS Certified Developer Associateも取得した。
スコアは791/1000。合格ラインが720なので、それほど余裕はなかった。
AWSを仕事でも使っているのと、特に勉強する時間が無いまま試験に臨んでしまった。Udemyで講座を買ったけど、結局ほとんど見ず。
AWSのサービスを一通り知識としては知っているが、実際に使ったことがないものも多いので、具体的なことについて問われると困ってしまった問題が多かった。
Kinesisとか、ElasticBeanstalkとか、Cognitoとか、実際触ってみないと。
次はProfessionalだけど、いきなり受けても受かる気がしないので、まずは模擬試験から。
試験に受かると特典として次の任意の試験料の50% Off になったり、模擬試験が無料になったりする。今回は模擬試験無料のコードを使った。
これからの一ヶ月で仕事DevOps分野をかなりやると思うので、AWS Certified DevOps Engineer - Professional Practice を受けてみる。 オンライン試験だから任意のタイミングでいつ受けてもいいのだが、4月18日に予定を入れた。日時を決めて取り組んで習慣化していきたい。
ちょっとした雑事でEC2でnginx使おうと思って、Amazon Linux 2 を初めて使ってEC2インスタンスをたててみた。
これまでのAmazon Linuxだと普通にyumが使えたと思うのだけど、今回は違った
$ sudo yum install nginx 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd パッケージ nginx は利用できません。 エラー: 何もしません nginx is available in Amazon Linux Extra topic "nginx1.12" To use, run # sudo amazon-linux-extras install nginx1.12 Learn more at https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras [ec2-user@ip-172-31-44-107 ~]$ sudo yum install nginx1.12 読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd パッケージ nginx1.12 は利用できません。 エラー: 何もしません
下記でインストールできた。
$ sudo amazon-linux-extras install nginx1.12 Installing nginx
$ amazon-linux-extras 0 ansible2 available [ =2.4.2 =2.4.6 ] 2 httpd_modules available [ =1.0 ] 3 memcached1.5 available [ =1.5.1 ] 4 nginx1.12=latest enabled [ =1.12.2 ] 5 postgresql9.6 available [ =9.6.6 =9.6.8 ] 6 postgresql10 available [ =10 ] 8 redis4.0 available [ =4.0.5 =4.0.10 ] 9 R3.4 available [ =3.4.3 ] 10 rust1 available \ [ =1.22.1 =1.26.0 =1.26.1 =1.27.2 =1.31.0 ] 11 vim available [ =8.0 ] 13 ruby2.4 available [ =2.4.2 =2.4.4 ] 15 php7.2 available \ [ =7.2.0 =7.2.4 =7.2.5 =7.2.8 =7.2.11 =7.2.13 =7.2.14 ] 16 php7.1 available [ =7.1.22 =7.1.25 ] 17 lamp-mariadb10.2-php7.2 available \ [ =10.2.10_7.2.0 =10.2.10_7.2.4 =10.2.10_7.2.5 =10.2.10_7.2.8 =10.2.10_7.2.11 =10.2.10_7.2.13 =10.2.10_7.2.14 ] 18 libreoffice available [ =5.0.6.2_15 =5.3.6.1 ] 19 gimp available [ =2.8.22 ] 20 docker=latest enabled \ [ =17.12.1 =18.03.1 =18.06.1 ] 21 mate-desktop1.x available [ =1.19.0 =1.20.0 ] 22 GraphicsMagick1.3 available [ =1.3.29 ] 23 tomcat8.5 available \ [ =8.5.31 =8.5.32 =8.5.38 ] 24 epel available [ =7.11 ] 25 testing available [ =1.0 ] 26 ecs available [ =stable ] 27 corretto8 available [ =1.8.0_192 =1.8.0_202 ] 28 firecracker available [ =0.11 ] 29 golang1.11 available [ =1.11.3 ] 30 squid4 available [ =4 ] 31 php7.3 available [ =7.3.2 ] 32 lustre2.10 available [ =2.10.5 ]
現時点で使えるパッケージのリスト。かなり最新版が使える。
FACTFULNESS(ファクトフルネス) 10の思い込みを乗り越え、データを基に世界を正しく見る習慣
話題になっている本だが、読んでよかった。世界は少しずつであるが確実に良くなっており、前向きな気持ちになれる。ただし、やたらと明るいというよりは、静かに光を見いだせる感じだ。
私が学生の頃は、「先進国」「発展途上国」という2分法で国を分類して学んだ。そのような区分は現在ではあてはまらなくなっているが、以前の認識のまま、国に対するイメージをもってしまいがちだ。 むしろ国内の格差のほうが問題になってきていて、日本の富裕層と中国の富裕層は似通っていて暮らしぶりも近いが、日本国内の富裕層と貧困層ではかなりの暮らしの違いがある。文化も考え方も違う。
本書で紹介されているような10個の傾向は心の中に留めておきたい。 これは、項目によっては「世界」という切り口でなくても、ある種のグループについての言説においては当てはまるものがある。
受かった。 スコアは849点(1000点満点)。「セキュアなアプリケーションおよびアーキテクチャを規定する」のセクションだけ「再学習を要する」となっていて、あとは「十分な知識を有する」に分類されていた。 S3とか通信の暗号化周りの理解が浅かった感じ。
下記のリンクはデジタルバッジ。
Solutions Architect Associateの資格は2013年くらいに一度取得していたがその後更新せずExpireしてしまっていた。AWSはそのときからすごく変化しているので取り直した。その頃には扱っていなかった機能も多く出題されていたと思う。
試験は渋谷のテストセンターで受けた。試験が終わった瞬間に結果が表示されるが、スコアとか認定証とかは数日後にメールでリンクが送られてくる。
テスト勉強は下記の書籍に2回くらい目を通しただけで、4時間くらいかけた。 普段仕事でAWSを使っていることもあり、既存の知識でほぼ回答できた。
徹底攻略 AWS認定 ソリューションアーキテクト ? アソシエイト教科書
2019年2月はちょうど試験内容が更改されたタイミングらしい。が、そこまで違う感じはしなかった。
AWS Certified Developer - Associateを3月13日に設定。 Solutions Architect Professinalに行きたかったけど、サンプル問題をパット見た感じ1ヶ月で受かる感じがしなかったので、ハードル低くしてDeveloperパスに進んでみようと思う。
OSQuery知らなかった。Facebookは個人情報面ではEvilなところがあるけど、作るOSSは良いものがある。
macならbrewで入る。ただしboostやらいろいろな依存ライブラリを入れるので結構時間がかかる。
必要になったらもっと調べたいけどとりあえず
> osqueryi
でインタラクティブシェルに入って
osquery> select * from os_version; +----------+---------+-------+-------+-------+--------+----------+---------------+----------+ | name | version | major | minor | patch | build | platform | platform_like | codename | +----------+---------+-------+-------+-------+--------+----------+---------------+----------+ | Mac OS X | 10.14.3 | 10 | 14 | 3 | 18D109 | darwin | darwin | | +----------+---------+-------+-------+-------+--------+----------+---------------+----------+
osquery> select percent_remaining from battery; +-------------------+ | percent_remaining | +-------------------+ | 100 | +-------------------+
とか。
参考
前回の続きで、今度はOperator SDKを使ってGoでControllerを書くかたちでOperatorを作ってみる。
下記を参照しながら作っていくが、例ではMemcachedのDeployment(レプリカ数:3)となっているが、これをmackerel-agentのDaemonSetとして作ってみる。 operator-sdk/user-guide.md at master · operator-framework/operator-sdk · GitHub
SDKのインストールまでは済んでいるので、プロジェクトの雛形を生成する。
ᐅ operator-sdk new mackerel-operator INFO[0000] Creating new Go operator 'mackerel-operator'. INFO[0000] Created cmd/manager/main.go INFO[0000] Created build/Dockerfile (中略) (68/70) Wrote k8s.io/apiextensions-apiserver@0fe22c71c47604641d9aa352c785b7912c200562 (69/70) Wrote github.com/coreos/prometheus-operator@v0.26.0 (70/70) Wrote sigs.k8s.io/controller-tools@v0.1.8 INFO[0095] Run dep ensure done INFO[0095] Run git init ... Initialized empty Git repository in /Users/yamadanaoyuki/go/src/github.com/mackerel-operator/.git/ Auto packing the repository in background for optimum performance. See "git help gc" for manual housekeeping. INFO[0103] Run git init done INFO[0103] Project creation complete.
ある程度まで、コードが自動生成される。
ᐅ operator-sdk add api --api-version=kirishikistudios.com/v1alpha1 --kind=Mackerel INFO[0000] Generating api version kirishikistudios.com/v1alpha1 for kind Mackerel. INFO[0000] Created pkg/apis/kirishikistudios/v1alpha1/mackerel_types.go INFO[0000] Created pkg/apis/addtoscheme_kirishikistudios_v1alpha1.go INFO[0000] Created pkg/apis/kirishikistudios/v1alpha1/register.go INFO[0000] Created pkg/apis/kirishikistudios/v1alpha1/doc.go INFO[0000] Created deploy/crds/kirishikistudios_v1alpha1_mackerel_cr.yaml INFO[0001] Created deploy/crds/kirishikistudios_v1alpha1_mackerel_crd.yaml INFO[0005] Running deepcopy code-generation for Custom Resource group versions: [kirishikistudios:[v1alpha1], ] INFO[0007] Code-generation complete. INFO[0008] Running OpenAPI code-generation for Custom Resource group versions: [kirishikistudios:[v1alpha1], ] INFO[0009] Created deploy/crds/kirishikistudios_v1alpha1_mackerel_crd.yaml INFO[0009] Code-generation complete. INFO[0009] API generation complete.
ᐅ operator-sdk add controller --api-version=kirishikistudios.com/v1alpha1 --kind=Mackerel INFO[0000] Generating controller version kirishikistudios.com/v1alpha1 for kind Mackerel. INFO[0000] Created pkg/controller/mackerel/mackerel_controller.go INFO[0000] Created pkg/controller/add_mackerel.go INFO[0000] Controller generation complete.
メインロジックである pkg/controller/mackerel/mackerel_controller.go
の中身を少しみてみると
(コードはこちら)
found := &appsv1.DaemonSet{} err = r.client.Get(context.TODO(), types.NamespacedName{Name: Mackerel.Name, Namespace: Mackerel.Namespace}, found) if err != nil && errors.IsNotFound(err) { // Define a new Daemonset dep := r.daemonsetForMackerel(Mackerel) reqLogger.Info("Creating a new Daemonset", "Daemonset.Namespace", dep.Namespace, "Daemonset.Name", dep.Name) err = r.client.Create(context.TODO(), dep) if err != nil { reqLogger.Error(err, "Failed to create new Daemonset", "Daemonset.Namespace", dep.Namespace, "Daemonset.Name", dep.Name) return reconcile.Result{}, err } // Daemonset created successfully - return and requeue return reconcile.Result{Requeue: true}, nil }
r.clientというのはKubernetesのCRUDをできるクライアントを内蔵していて、実際に必要なリソース(今回はMackerelというCR)があるかどうかチェックして無ければ作成する、ということをやっている。
DaemonSetのリソースは下記のようにGoの構造体として生成するのだが、慣れないとYamlを書いたほうが簡単に感じる。コード補完に頼りつつ、ドキュメントを見つつ書いた。
func (r *ReconcileMackerel) daemonsetForMackerel(m *apiv1alpha1.Mackerel) *appsv1.DaemonSet { ls := labelsForMackerel(m.Name) dep := &appsv1.DaemonSet{ TypeMeta: metav1.TypeMeta{ APIVersion: "extensions/v1beta1", Kind: "DaemonSet", }, ObjectMeta: metav1.ObjectMeta{ Name: m.Name, Namespace: m.Namespace, }, Spec: appsv1.DaemonSetSpec{ Selector: &metav1.LabelSelector{ MatchLabels: ls, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: ls, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{{ Image: "mackerel/mackerel-agent:latest", Name: "mackerel-agent", Env: []corev1.EnvVar{ { Name: "apikey", //TODO get from ConfigMap or Secret Value: "xxxxxxxxxxxxxx", }, { //TODO get from ConfigMap or Secret Name: "opts", Value: "-role=minikube:mbp13", }, { Name: "enable_docker_plugin", Value: "1", }, }, VolumeMounts: []corev1.VolumeMount{ { Name: "docker-sock", MountPath: "/var/run/docker.sock", }, { Name: "mackerel-id", MountPath: "/var/lib/mackerel-agent/", }, }, }}, Volumes: []corev1.Volume{ { Name: "docker-sock", VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{Path: "/var/run/docker.sock"}, }, }, { Name: "mackerel-id", VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{Path: "/var/lib/mackerel-agent/"}, }, }, }, }, }, }, } // Set Mackerel instance as the owner and controller _ = controllerutil.SetControllerReference(m, dep, r.scheme) return dep }
ᐅ kubectl create -f deploy/crds/kirishikistudios_v1alpha1_mackerel_crd.yaml customresourcedefinition.apiextensions.k8s.io "mackerels.kirishikistudios.com" created
ᐅ operator-sdk build chokkoy/mackerel-operator:v0.0.1 INFO[0004] Building Docker image chokkoy/mackerel-operator:v0.0.1 Sending build context to Docker daemon 197.9MB Step 1/7 : FROM alpine:3.8 ---> 491e0ff7a8d5 Step 2/7 : ENV OPERATOR=/usr/local/bin/mackerel-operator USER_UID=1001 USER_NAME=mackerel-operator ---> Using cache ---> 23212d49d23b Step 3/7 : COPY build/_output/bin/mackerel-operator ${OPERATOR} ---> 508598d68109 Step 4/7 : COPY build/bin /usr/local/bin ---> 82ea47e91962 Step 5/7 : RUN /usr/local/bin/user_setup ---> Running in 20736001278d + mkdir -p /root + chown 1001:0 /root + chmod ug+rwx /root + chmod g+rw /etc/passwd + rm /usr/local/bin/user_setup Removing intermediate container 20736001278d ---> 495bc12d5160 Step 6/7 : ENTRYPOINT ["/usr/local/bin/entrypoint"] ---> Running in b3dbe6930311 Removing intermediate container b3dbe6930311 ---> d159180ac21f Step 7/7 : USER ${USER_UID} ---> Running in 3cf2c8f425b3 Removing intermediate container 3cf2c8f425b3 ---> 99d8a5dbf5f3 Successfully built 99d8a5dbf5f3 Successfully tagged chokkoy/mackerel-operator:v0.0.1 INFO[0012] Operator build complete.
ᐅ docker push chokkoy/mackerel-operator:v0.0.1
このイメージ名:タグ
で deploy/operator.yamlのIMAGEを置き換えて、デプロイ
ᐅ kubectl create -f deploy/service_account.yaml serviceaccount "mackerel-operator" created ᐅ kubectl create -f deploy/role.yaml role.rbac.authorization.k8s.io "mackerel-operator" created ᐅ kubectl create -f deploy/role_binding.yaml rolebinding.rbac.authorization.k8s.io "mackerel-operator" created ᐅ kubectl create -f deploy/operator.yaml deployment.apps "mackerel-operator" created
この状態で、OperatorのDeployment(Pod)が一台起動している
ᐅ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE mackerel-operator 1 1 1 1 6s
ᐅ kubectl get pods NAME READY STATUS RESTARTS AGE mackerel-operator-557ff88b57-gjh9w 1/1 Running 0 9s
ᐅ kubectl apply -f deploy/crds/kirishikistudios_v1alpha1_mackerel_cr.yaml mackerel.kirishikistudios.com "example-mackerel" created
すると、mackerel-agentのDaemonSetが起動する。
ᐅ kubectl get pods NAME READY STATUS RESTARTS AGE example-mackerel-4m7d7 1/1 Running 0 7s mackerel-operator-557ff88b57-gjh9w 1/1 Running 0 30s
ᐅ kubectl get ds NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE example-mackerel 1 1 1 1 1 <none> 10s
SDKを使ってOperatorを作る流れがなんとなくわかった。GoでKubernetesのリソースを制御できるのは面白い!
ソースコードはこちら