xrandrの設定をスリープからの復帰時に自動的に適用する
https://forums.linuxmint.com/viewtopic.php?t=288050
に書いてあることなんだけども、自分的にすごい満足度があがったのでメモ
- /lib/systemd/system-sleep/xrandr
内容は以下の通り
1 | `#!/bin/sh |
https://forums.linuxmint.com/viewtopic.php?t=288050
に書いてあることなんだけども、自分的にすごい満足度があがったのでメモ
内容は以下の通り
1 | `#!/bin/sh |
Mastodon 2.3.3
元々、mastodon.example.com で運用していた(アカウント名は hoge@example.com)
(要するに、.env.production で WEB_DOMAIN を指定してアカウント名と実際マストドンにアクセスする URL を変えていた)
いくつかのクライアントが、返信する際に、 hoge@mastodon.example.com と書いて返信して
しまうようだったので、マストドン自体の URL も example.com でアクセスできるように、
WEB_DOMAIN の指定を消したところ、トラブルに遭遇した。
トゥートを行うと、SideKiq の push ジョブが失敗して、retry キューに溜まってしまう。
現象はこの Issue の通り
https://github.com/tootsuite/mastodon/issues/6667
基本的には、対処方法はありません。元に戻すしかありません。。
しかも、URL 変更中に作成されたアカウント、かつ他インスタンスに登録されてしまうと、
戻したとしても新しいアカウントについて同じことが発生してしまいます。
しかし、Issue を見ると、他のインスタンスに既に登録されたアカウントと、URL の対応を変更する事ができず
アカウント名重複エラーとなっているようなので、自インスタンス側の全てのアカウントを作り直すことで
対応できます。(今回はほぼお一人様インスタンスだったので、こちらを選択しました)
アカウントと URL の対応の変更、下手に出来ちゃうとアカウント乗っ取りが可能になりかねないので
なかなか難しいのでしょうね。
2.8 くらいで、ユーザーを作り直す的なコマンドが toot-ctl に追加されているので、この記事の内容は古いかもしれません。
※ 多少読み替えて頂ければ、docker ではない Mastodon も移行できるはず
実は移行自体はそれほど難しくありません。
移行が必要なのは、PostgreSQL の DB だけです。redis のデータも移行した方がよいですが、
移行しなくてもその時点の Sidekiq のジョブが失われる程度で、恐らく誰も気づきません。
※ 管理者的には、Sidekiq 画面のジョブ数がリセットされるのが残念かな?程度
Deployment 定義を github に公開しています。
https://github.com/yakumo-saki/k8s-mastodon-deployment
私のインスタンスは、Glitch Edition なので Docker イメージ名が違いますが、基本的に
公開している Deployment をそのまま使用しています。
複数インスタンス持ちなので、myinstance をコピーして foundation としました。myinstance/kustomize.yaml は以下のように書き換えました。
1 | namePrefix: myinstance- # Pod名の先頭にmyinstance- をつける |
env.production ファイルは稼働中のインスタンスからそのまま持ってきます。
その上で、DB_HOST REDIS_HOST を変更します。
DB を戻し終わるまでは、Web, Streaming, Sidekiq には起動して欲しくありません。
そのため、一時的に ./base/kustomization.yaml を変更します。
1 | resources: |
ここまでできたら、
myinstance ディレクトリで
1 | $ kustomize build | kubectl apply -f - |
(リハーサルなら止めなくてよい)
DB と Redis コンテナ以外 を停止します。
1 | # 移行元インスタンスのdockerが動いてるところで |
pg_dumpall.sql dump.rdb ファイルは、kubectl を使用可能な PC にコピーしておいて下さい。
1 | $ kubectl cp pg_dumpall.sql myinstance-db-0:pg_dumpall.sql |
redis のバックアップは、 /data/dump.rdb を上書きするだけです。
しかし、一つ落とし穴があります。 それは、redis 稼働中に dump.rdb を上書きしても、
redis をシャットダウンする際に上書きされるという罠です。
なので、一旦 redis-server を起動しないようにします。
./base/redis-deployment.yaml を編集。
1 | <code class="language-yaml:./base/redis-deployment.yaml">(略) |
1 | $ kubectl get pod して、 myinstance-redis-* のpod を探す。 |
./base/redis-deployment.yaml を元に戻します。./base/kustmization.yaml を元に戻します。元に戻したら、いよいよ起動を行います。
1 | kustomize build | kubectl apply -f - |
とりあえず、 curl [外向きのIP等]:3000 して何かが帰ってくれば OK とします。
動作確認ができたら、リバースプロクシの設定を変更しましょう。
マウントしないといけないのですが、本稿では色々と事情があり割愛しています。
.env.production だと ls したときに表示されないからです。 ls -a すれば見えますが。
個人的に見えないファイルが重要っていうのはあんまり好きではないので。。単純に好みですね
Qrunch さんがサービス終了されてしまうそうなので、自前で Ghost をホストすることにしました。データの移行はまだ終わっていませんが、ぼちぼちやっていきます。
ちなみに、オンプレミスの kubernetes クラスタ上で動作しています。
URL を本番用のものに変えた時にリダイレクトループになってしまってかなり焦りました。
https://ghost.org/faq/change-configured-site-url/
ぐぐったら思いっきり FAQ でした。リバースプロキシが入っているのでヘッダをセットする必要があったという凡ミス。
nginx の設定ファイルに以下を追記するとうまく行きます。
1 | proxy_set_header X-Forwarded-Host $http_host; |
最後のデプロイスクリプトが、deploy ディレクトリの構造に依存している為、ディレクトリ名の変更等は
してはいけません。また、以下のファイル類は kubectl コマンドが使えればどのマシンに置いてあっても問題なさそうですが、
一応、kubernetes の master ノードで行いました。
/etc/modules-load.d/glusterfs.conf というファイル名で、GlusterFS の全ノードに以下の内容のファイルを配置します。
再起動ができれば再起動が一番良いですが、とりあえず modprobe でロードしてもよいと思います。
この作業は、GlusterFS のノード全てで必要です。(大事なので強調)
1 | dm_snapshot |
まずは、以下のリポジトリを clone します。ZIP でダウンロードでも OK です。
https://github.com/gluster/gluster-kubernetes/
使用するのは、deploy ディレクトリ以下のみなので、以下 deploy ディレクトリを基準に説明します。
topology.json.sample をコピーして topology.json とします。
内容は sample を見て頂いた方が早いと思います。
最近の kubernetes で変更になったオプションが使われている為、以下の issue の内容に従って gk-deploy を書き換えます。
具体的には、 --show-all を検索して、削除して下さい。
https://github.com/gluster/gluster-kubernetes/issues/582
1 | 例 |
gk-deploy スクリプトを実行します。失敗に備えて、一度本記事を最後まで読んでからやることをおすすめします。
1 | ./gk-deploy -gv -w 600 --admin-key admkey --user-key usrkey |
gk-deploy が成功すると、最後に、storageclass.yaml の内容が表示されます。
後で apply するので、 storageclass.yaml のような名前でファイルに保存して下さい。
表示される内容が誤っている場合があるので、 resturl: の指定が正しいことを確認して下さい。
resturl は、PV を確保する際に使用する heketi の API エンドポイントのアドレスです。
heketi はスクリプト内で自動的にデプロイされています。
エンドポイントは Service から取得することができます。具体的には以下です。
heketi_Endpoint 取得
1 | $ kubectl get svc heketi |
これで取得した IP アドレスとポートが、 storageclass.yaml 内に指定されているか確認して下さい。
当方が実行した際は、誤った値が表示されていました。
storageclass.yaml
1 | apiVersion: storage.k8s.io/v1beta1 |
ここまで確認したら、 kubectl apply -f storageclass.yaml で StorageClass を生成して完了です。
PVC を作成する際に、StorageClass 名を指定すれば良いのですが、省略された際にこの StorageClass が使用される
ようにする為には、default に指定する必要があります。
1 | kubectl patch storageclass glusterfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' |
適用されたかどうかは以下のコマンドで確認できます。
1 | > kubectl get sc |
この記事はここが書きたいので書きました。
1 | ./gk-deploy -gv -w 600 --admin-key admkey --user-key usrkey --abort |
末尾に --abort をつけるとやり直しができますが、途中でディスクに対して変更を行ってしまっている場合、abort しても
成功しません。 全ノードの topology.json で指定したディスクに対して wipefs --all /dev/sdb のように
各種シグネチャを削除する必要があります。
ありますが・・・ 恐らく、resource busy と言われて失敗するかもしれません。
その場合、一度ディスクをデタッチしてから再度行うと上手く行くと思います・・・が、恐らく、デバイス名が変わってしまいます。
最終的には再起動しかありません。(むしろご存じでしたら教えて下さい)
チェックリストは以下の通り。 上から順にチェックすると良いです。
なお、本文書は SpringBoot 1.2 ~ 1.4 の頃に書かれたものです。2.x になると少し事情が変わるかもしれません。
(2019/04/09 あまりにもそっけない文書だったので肉付け&改訂)
@Autowired したいフィールドが static の場合、インジェクションされません。
static を外しましょう。
@Component の付け忘れ@Autowired したいクラスに、 @Component がついていないと部品として認識されません。
ついてなければつけてみましょう。
ただし、これで直らなかった場合は別のアノテーションが @Component 相当の認識をされている
可能性が高いので元に戻しておきましょう。(害がない場合が多いと思いますが)
例えば、 @Service @Repository が既についているのであれば、部品として認識されるはずなので
@Component をつけても解決しません。
@Component されたクラスが @ComponentScan の範囲外@SpringBootApplication がついたクラスのパッケージとその配下のパッケージは自動的にスキャンされます。
しかし、それ以外のパッケージに存在するクラスは部品探索範囲外なので、部品として認識されません。
解決方法としては、
@SpringBootApplication のパッケージ(配下含む)に移動する@SpringBootApplication のついたクラスに、 @ComponentScan("パッケージ") を追加する@Autowired したいクラスは、 @Component ではない@Component ではないクラスは Spring の管轄外なので @Autowired は効きません。
@Component されたクラスの名前が他と重複しているSpringboot 等の依存ライブラリ内の部品と名前が重複している場合、無視される場合があります。
試しにクラス名を変えると上手くいくかもしれません。(正確には無視というより優先順位問題)
特に一般的な名前をクラスにつけたクラスのみが当てはまる場合、試してみる価値はあります。
ダメだった名前の例) Environment
@ComponentScan の書き方例1 | @ComponentScan(“org.example.somepackage”) |
1 | // この書き方は古いかもしれない |
boot from debian 10 ISO
<Installer GUI>
installation complete
from console
login as user
1 | iface eth0 inet static |
https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/
sudo su -
cat <
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo apt-get install -y iptables arptables ebtables
sudo update-alternatives –set iptables /usr/sbin/iptables-legacy
sudo update-alternatives –set ip6tables /usr/sbin/ip6tables-legacy
sudo update-alternatives –set arptables /usr/sbin/arptables-legacy
sudo update-alternatives –set ebtables /usr/sbin/ebtables-legacy
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
reboot
Knockout.js 3.3.0 を使い始めて数週間ですが、
とりあえずハマった事をメモします。
JSON から Knockout の Observable を作ってくれる便利なプラグインですが…
ko_mappings みたいなのが付いてしまう。
→ ko.mapping.toJSON を使う必要がある。
編集のロールバックや、変更されたか否かを自動で判定してくれる便利なもの。
ko.mapping.toJSON したときに余計なプロパティが
付いてしまう。(で、例えば Java とか型の固い言語に JSON 化して引き渡すと hasChanges を
解釈できずにコケる)
→ どうにもならないので、ko.mapping 側の ignore に追加する。hasChanges という名前をフィールドに使えなくなるが仕方が無い(editable 使う時点で使えないし)
http://knockoutjs.com/documentation/plugins-mapping.html
1 | ko.mapping.defaultOptions().ignore = ["hasChanges"]; |
→FAQ らしい。observableArray は中身について一切関知しない。
なので、追加/削除の時しか通知は来ない。
see: http://kojs.sukobuto.com/docs/observableArrays
・・・でもこれ、直感的な動作とは言いがたいような気がする。
ObservableArray の中身のプロパティを、ko.observable で定義して(ko.mappings 使えば自動)
Array 内の全てのオブジェクトの、必要なプロパティに Subscribe すれば良い。
Subscribe するときは、次の項目の通り、 this に束縛する値に都合のよいものを指定する。
Subscribe するときの第二引数で、ハンドラの this に束縛する値をセットする必要がある。
Subscribe した時に返ってくるオブジェクト.dispose() すれば OK。
1 | ko.utils.arrayForEach(array.items(), function (item) { |
実装されてないのでどうにもならない模様。私は諦めた。
ただし、中身は普通に Observable なはずなので、subscribe できるはず。
ViewModel 一個で画面を作っている場合、$root = $parent となるのが大半でしょう。
この時、できるだけ $parent で指定しておいた方が良いです。
後々、画面が複雑化してきて、複数 ViewModel に分割した場合(以下例参照)
1 | // 例えばこんな感じです |
元々$root で取得していたものは $root.main で参照するようになります。
$rootを使っている箇所、全て書き直しになってしまうので、$parent を
できるだけ使う事をおすすめします。というより、$root を使わないといけないことは
滅多にないはずです。
→2015/08/30 追記
そもそも、大きく囲んだ要素に data-bind=”with: main” と書いてあるのであれば
main の viewModel の中の要素を指定する際、プレフィックス的なものは不要。
とりあえず data-bind=”with:hoge” を書いておいた方が収まりがいいと感じた。
バインディングコンテキストは理解しておいた方がよさそう。
-> 2015/09/30 追記
viewModel が一つしかない場合でも、ko.applyBindings(viewModel); は使わずに
上のコードのように連想配列を渡しておけば、後からVM分割したくなっても安心。
if は、条件が false な時に、その中の要素を本当に消してしまいます。
条件が成立すると、中の要素を追加します。何が問題かというとバインドした
イベントが消えるということです。
visible であれば隠れるだけなのでこういった問題は発生しません。
https://mackerel.io/ja/docs/entry/howto/install-agent
Ubuntu16 以降なので以下のコマンド。と言っても、Mackerel の Web にログイン状態で、Hosts→ 右上のエージェントをインストール を選択すると OS の選択肢が表示されて、そこから選ぶとコマンドが完璧な形で表示されるのでそこをコピペすることをおすすめします。
1 | wget -q -O - https://mackerel.io/file/script/setup-all-apt-v2.sh | MACKEREL_APIKEY='<YOUR_API_KEY>' sh |
全部のプラグインがセットになっています。
1 | apt-get install mackerel-agent-plugins |
Mackerel のプラグインは CLI からテストできる。楽。
1 | mackerel-plugin-postgres -user=postgres -password=postgres_pwd [-database=<databasename>] |
なお、最初は同じコマンドを二度実行しないと警告が表示されます。
1 | postgres.tempfile.temp_bytes 0.000000 1534094514 |
設定ファイルに実行する内容を記述する必要があります。
/etc/mackerel-agent/mackerel-agent.conf を編集します。
すでに plugin の設定サンプルが書かれているので、コメントアウトするだけ…
ではありません 設定例は以下のような形になります。
1 | [plugin.metrics.postgres] |
ようするに command = "先程テストしたコマンドラインそのまま"
です。これに気づかず、少しハマりました。
他のプラグインでパラメタがないものについては、設定ファイルのコメントアウトを外すだけで有効になります。
各プラグインの説明は・・・ https://github.com/mackerelio/mackerel-agent-plugins
これなんですかねぇ… 割と淡白な説明ですがなんとかなると思います。
Docker を動かす為のできるだけ小さい構成の OS を捜していた。
Arch は全部自分でパッケージ入れて好きに構成するという考え方らしいので
できるだけ最小にできるはず!ということでやってみた記事です。(なお初めてです)
手順は以下を参照しながらやっています
https://dzone.com/articles/install-arch-linux-on-windows-10-hyper-v
Arch の ISO をマウントして起動する。
すると、自動的に root のプロンプトが起動してくる。
コンソールではコピペもできず不便なので、ssh が使えるようにする。
1 | localectl set-keymap jp106 |
EFI で起動させたいので、GPT でパーティションを切っていく。
1 | $ gdisk /dev/sda |
1 | mkfs.fat -F32 /dev/sda1 |
1 | mount /dev/sda2 /mnt |
1 | pacstrap /mnt base base-devel openssh vim |
1 | default arch |
1 | cp /usr/share/systemd/bootctl/arch.conf /boot/loader/entries/ |
blkid -s PARTUUID -o value /dev/sda2
で UUID を取得しておく。
vim /boot/loader/entries/arch.conf
1 | options root=PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rootfstype=ext4 add_efi_memmap |
1 | bootctl update |
これで再起動できます。おつかれさまでした。
固定 IP を指定する。DHCP 使わない。Network-manager もナシ
1 | vim /etc/systemd/network/20-wired.network |
1 | [Match] |
1 | systemctl enable systemd-networkd |
1 | vim /etc/locale.gen |
1 | sudo locale-gen |
1 | sudo localectl set-locale LANG=en_US.UTF-8 |
ここで一度 SSH を切断して、再接続しないと表示乱れが発生した。
1 | sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime |
1 | $ date |
1 | hostnamectl set-hostname ほすとめい |