2017年11月27日月曜日

389 Directory と AD の連携 (LDAP->AD 編)


前々回の389 Directory と AD の連携 (AD-> LDAP 編)の設定で双方向レプリケーションは自然に出来ているはず。が、どうも私の環境だとうまく行かない。389 Directory 側のエントリを modify しても AD に伝播してくれないのだ。

エラーログには以下のメッセージが。

NSMMReplicationPlugin - replica_update_state - Failed to update state of csn generator for replica dc=example,dc=com: LDAP error - 32

該当箇所のソースを見たがすぐにわかるようなものじゃないことが判明。仕方なくデバッグログ(nsslapd-errorlog-level: 8320)を出してみる。すると以下が。

Received result code 50 (00002098: SecErr: DSID-03150E49, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0 ) for modify operation

見覚えのあるエラー。AD 側に作ったレプリケーション用ユーザの権限が甘かったらしい。このユーザを Domain Admins グループに追加したところ OK。ここに書いてあった「Write/Create all child objects/Delete all child objects/Add GUID」は全部確認したんだけどなぁ...

まぁともあれ双方向レプリケーションは出来た。ちなみに LDAP-> AD 向きのパスワード同期については、ldappasswd (LDAPv3 Password Modify -RFC 3062) では駄目で、ldapmodify で userPassword に対して生パスワードを設定する必要がある。



2017年11月25日土曜日

Container Linux Config

Container Linux の設定が coreos-cloudinit でなく "Container Linux Config" で行うようになったけど、自分の頭の中の切り替えも結構必要なようだ。

普段 Vultr で CoreOS を使ってるが、running な CoreOS の設定(コンテナじゃなくて CoreOS 自体の設定)を変更しなくちゃならんときは、/usr/share/oem/cloud-config.yml をいじれば何とかなる。しかし、GCE の CoreOS や最新の PXE のイメージで標準になってる "Container Linux Config" の Ignition は本当に起動時にだけ実行され(see: https://coreos.com/ignition/docs/latest/what-is-ignition.html#when-is-ignition-executed)るとのこと。じゃぁ running で設定を変更したいときはどうするんじゃと...

https://www.bountysource.com/issues/43393940-edit-user-in-cloud-config-yml-remains-the-old-one-why あたりを見る限りは、Ignition には ignition.json を変更するというユースケースはないとのこと。

おそらく CoreOS 自体(コンテナじゃなくて)を永続化させるってのが、既にコンセプトと違うんだろう。etcd ver.3 (etcd-member)からは rkt の別コンテナで動かすようになってるし、とにかくステートを持つものはコンテナとして起動させろってことなんだろう。

全然関係ないけど、Vultr でインスタンスを作る時に「CoreOS」という名前のままなのは、レガシィな cloudinit 使ってるからなのか? あ、さらに関係ないけど、Vultr で Container Linux を iPXE で起動しようとして失敗するのは、たいていリソースが足りないからのようだ。Container Linux の本家のドキュメントには initrd を広げるのに最低 2GB の RAM が必要ということだ。ケチって 1GB RAM にすると失敗する。ケチりたいときは iPXE でなく既に用意されている CoreOS で cloud-config.yml をちまちまいじるしかないかも。

2017年11月21日火曜日

389 Directory と AD の連携 (AD->LDAP PassSync編)

先日の389 Directory と AD の連携 (AD-> LDAP 編)の続き。

前回は AD からアカウントの同期は出来るようになった。今回は AD 側でユーザが変更した(管理者が変更するのでもOK)パスワードを、389 Directory に送って同期するようにしてみる。

似たような仕組みは以前自分でも会社のプロジェクトで作ったことがあって、そのときは Windows 上の LSA(Local Security Authority) ってのがコールバックする PasswordChangeNotify() 関数を実装したけどおそらく同じ仕組みだろう。後で 389 のソース確認してみる->自分。

  1. まずは、389 Directory を LDAPS 化する。生でも行けるのかも知れんが、99 % のお客さんは暗号化して欲しいって言ってくるだろう。ただそんな場合でもオレオレ証明書(Self-Signed)で十分。なのでまずは 389 Directory に入れる証明書と秘密鍵を作って certutil に噛ませるために PKCS#12 にする。ここで -name で指定する friendlyname は Server-Cert という名前にしないと後で苦労するっぽい(この情報は Web のどこかに書いてあったんだけど見失ってしまった...)
  2. openssl req -x509 -newkey rsa:2048 -keyout 389.key -out 389.crt
    openssl pkcs12 -export -out 389.p12 -inkey 389.key -in 389.crt -name Server-Cert
    
  3. 上記でできた 389.p12 ファイルを pk12util で /etc/dirsrv/slapd-<インスタンス名>/ 下の NSS データベースに登録。
  4. pk12util -i 389.p12 -d /etc/dirsrv/slapd-ryo/
    
    PKCS#12 のパスワードやデータベースのパスワードを聞かれるので適切に応答する。そして登録できたか確認
    # certutil -L -d /etc/dirsrv/slapd-ryo
    Certificate Nickname                                         Trust Attributes
                                                                 SSL,S/MIME,JAR/XPI
    Windows Server AD CA cert                                    P,,  
    Server-Cert                                                  u,u,u
    
    Server-Cert って証明書があるのがわかる。ちなみにその上の Windows Server AD CA cert ってのは前回作った Windows Server 側の証明書。秘密鍵も確認。
    # certutil -K -d /etc/dirsrv/slapd-ryo
    certutil: Checking token "NSS Certificate DB" in slot "NSS User Private Key and Certificate Services"
    Enter Password or Pin for "NSS Certificate DB":
    < 0> rsa      1xxxxxxxxxxxxxxxaff5b7826ec1dxxxxxxxxxx   Server-Cert
    
    ちなみに何らか失敗して p12 ファイルの登録をやり直したい場合に証明書と秘密鍵を消すが、これを certutil の -D で証明書だけ消すと秘密鍵が消せなくなるので注意。この場合は再度同じ p12 を登録してから certutil の -F オプションを使うとよい。数年前のコミュニティの ML でバグだって言っている人がいたが、直してないところをみるとディベロッパはバグじゃないと思ってるんだろう。

  5. あとは 389 Directory の設定に証明書の情報を入れるため以下 ldif を ldapmodify (-D "cn=Directory Manager")で登録。詳細は公式ドキュメント参照。
  6. dn: cn=encryption,cn=config
    changetype: modify
    replace: nsSSL3
    nsSSL3: off
    -
    replace: nsSSLClientAuth
    nsSSLClientAuth: allowed
    -
    add: nsSSL3Ciphers
    nsSSL3Ciphers: +all
    
    dn: cn=config
    changetype: modify
    add: nsslapd-security
    nsslapd-security: on
    -
    replace: nsslapd-ssl-check-hostname
    nsslapd-ssl-check-hostname: off
    
    続けて同様に ldapmodify で、以下 ldif を登録。これは後述の /etc/dirsrv/dirsrv/slapd-<インスタンス名>/下の pin.txt ってファイル(これも ldif ぽい)に関する設定のようだ。以下の nsSSLToken というのは、pin.txt の中の属性名を指し示している模様。
    dn: cn=RSA,cn=encryption,cn=config
    changetype: add
    objectclass: top
    objectclass: nsEncryptionModule
    cn: RSA
    nsSSLPersonalitySSL: Server-Cert
    nsSSLToken: internal (software)
    nsSSLActivation: on
    
  7. NSS データベースのパスワードファイル /etc/dirsrv/slapd-<インスタンス名>/pin.txt を以下のように作成。左辺の「internal (software)」は上記の nsSSLToken の値であることに注意。
  8. internal (software):secret
    
    パーミッションを dirsrv:dirsrv の 0400 にする。
    # chown dirsrv:dirsrv /etc/dirsrv/slapd-ryo/pin.txt
    # chmod 400 /etc/dirsrv/slapd-ryo/pin.txt
    
  9. あとは dirsrv (ns-slapd)を再起動するだけ。
  10. systemctl restart dirsrv@ryo
    
    ss すれば 636 で listen してるはず。

  11. 上記までで LDAPS 化は完了して、あとは AD 側の設定。公式ドキュメント(Installing PassSync)のところに Windows 用バイナリのリンクがあるので、ダウンロードしてインストールする。インストーラの最初の画面で以下の項目を入力する必要がある。
    • Host Name: 389 Directory サーバの FQDN
    • Post Number: LDAPS ポート(636)
    • User Name: 前回 389 Directory 上に作ったレプリケーション用ユーザ (cn=sync user,cn=config)
    • Password: 上記レプリケーション用ユーザのパスワード
    • Cert Token: よくわからない。必須でないので空っぽ。
    • Search Base: 同期するユーザの 389 Directory 側の Base DN

  12. Windows Server に PassSync をインストールし終わったら、PassSync に 389 Directory の LDAPS のサーバ証明書を certutil.exe でインポートする。公式ドキュメント(Configuring PassSync)参照のこと。ここで注意したいのが、前回同様 certutil.exe の -t オプションを "P,," とすること。
  13. cd "C:\Program Files\389 Directory Password Synchronization"
    certutil.exe -d . -A -n "DS CA cert" -t "P,," -a -i \path\to\389.crt
    
    ここで Windows お得意のマシンごと再起動。

  14. 389 Directory に戻ってひとつだけ前回にやっていなかったことがあって、それをやらなくてはならない。前回はレプリケーション用ユーザの "cn=sync user" を 389 Directory 上に作ったが、このユーザに userPassword 属性の書込を許可する aci を与えていなかった。以下 ldif を ldapmodify (-D "cn=Directory manager") で登録する必要がある
  15. dn: ou=people,dc=example,dc=com
    changetype: modify
    add: aci
    aci: (targetattr="userPassword")(version 3.0;acl "password sync";allow (write,compare) userdn="ldap:///cn=sync user,cn=config";)
    

  16. 上記までで設定は完了。 AD 側で、あるユーザのパスワードを変更すると 389 Directory 側の対応するユーザの userPassword 属性が変更されるはず。うまく行かない場合は、Windows Server 側の C:\Program Files\389 Directory Password Synchronization/passsync.log を確認すると良い。



2017年11月17日金曜日

PNF No Root

子供にスマホを買い与えるな馬鹿親!って議論は置いておいて、とりあえず Google の Find My Device (端末を探す)でうちの子がどこにいるかを知りたいわけですよ。
まだそういう監視下に置かせるべき年頃なので。

で、最近 g06+ なるスマホを買って子供に渡す前に、DMM Mobile のデータ SIM (SMS付き)を入れていろいろ実験してみたところ、どうも Find My Device で Can't find device が頻発する事象に悩まされることに。

自分の Nexus 6P + Softbank SIM は全然いつでも Find OK なのに何で? といろいろと調べたところ、以下がヒット。

スリープ後、時間が経つとプッシュ通知が来なくなる件
どうも、格安 SIM に多い現象ということ。上記 URL によれば MVNO 側の NAT テーブルのタイムアウトが、Google の PUSH サーバの Keep-Alive の間隔より短いらしい(ん?NATってことは MVNO が IPv6 対応なら問題ないのかな)。

まぁ Find My Device も PUSH 通知とセッションの維持の仕方は似たようなもんだろうから、早速上記 URL にあった PNF No Root を入れてその間隔を18 分に設定。おぉ、見違えるほど反応がよくなった。副作用として、バッテリーの減り方も遅くなったぞ。うん。

まぁ DMM Mobile の SIM はあくまでも実験で使ってるんであって、最終的には mineo の 音声 SIM を入れるんだけど。

悩んでいる人はお試しください。

389 Directory と AD の連携 (AD-> LDAP 編)

また 389 Directory ネタ。 AD と連携できるってことで、「やってみた」レベルのことをやってみたのメモ。GUI 無し, とりあえず AD -> LDAP 方向のみ。オレオレ証明書で AD からの LDAPS。

  1. まず、389 Directory をインストール。OS は CentOS 7。Java の admin GUI は使わないので setup-ds.pl を使う。問答の途中でインストールタイプを聞かれるが、私はこれはカスタマイズしやすい 3 で作る。なお、インスタンス名は ryo , サフィックスは example.com とした。
    
    # yum install 389-ds-base
    # setup-ds.pl
    
  2. AD は Windows Server 2012 R2。このインストールや設定はここでは説明しません。適当にご自由に。なお、ここでは説明上 example.local という AD ドメインを設定した。
  3. オレオレ証明書を作って AD に入れて LDAPS させる。手前味噌だが以下を参照で。

    AD でオレオレ証明書で ldaps するのに AD CS で作った証明書じゃないとダメというデマ
    http://blogger.fastriver.net/2014/02/ad-ldaps-ad-cs.html
  4. 上記オレオレ証明書(ここでは my.crt とした)を 389 Directory にセット。
  5. 
    # cd /etc/dirsrv/slapd-ryo/
    # certutil -d . -A -n "Windows Server AD CA cert" -t P,, -a -i /path/to/my.crt
    

    ここで注意したいのが、-t オプションの値を「P,,」(Valid Peer)としてるところ。オレオレの時は C (Trusted CA) じゃなくてサーバ証明書そのものを信頼される証明書として指定すべきぽい。
  6. AD 側にレプリケーション用のユーザを作成する。これは以下の URL に従った。権限として「Write/Create all child objects/Delete all child objects/Add GUID」が必要とのこと。なお、ここではこのユーザの DN は「cn=replication,cn=Users,dc=example,dc=local」とした。

    http://directory.fedoraproject.org/docs/389ds/howto/howto-windowssync.html#creating-ad-user-with-replication-rights
  7. あとは 389 側にいろいろ ldif で設定を入れる。ldapmodify で -D 'cn=Directory Manamger' で接続すること前提。
    • suffix のエントリの作成。
    • dn: dc=example,dc=com
      changetype: add
      objectClass: top
      objectClass: domain
      dc: example.com
      aci: (targetattr!="userPassword || aci")(version 3.0; acl "Enable anonymous ac
       cess"; allow (read, search, compare) userdn="ldap:///anyone";)
      aci: (targetattr="carLicense || description || displayName || facsimileTelepho
       neNumber || homePhone || homePostalAddress || initials || jpegPhoto || labele
       dURI || mail || mobile || pager || photo || postOfficeBox || postalAddress ||
       postalCode || preferredDeliveryMethod || preferredLanguage || registeredAddr
       ess || roomNumber || secretary || seeAlso || st || street || telephoneNumber 
       || telexNumber || title || userCertificate || userPassword || userSMIMECertif
       icate || x500UniqueIdentifier")(version 3.0; acl "Enable self write for commo
       n attributes"; allow (write) userdn="ldap:///self";)
      aci: (targetattr ="*")(version 3.0;acl "Directory Administrators Group";allow 
       (all) (groupdn = "ldap:///cn=Directory Administrators, dc=example,dc=com");)
      
    • people コンテナの作成
    • dn: ou=people,dc=example,dc=com
      changeType: add
      objectclass: top
      objectclass: organizationalUnit
      ou: people
      
    • changelog の有効化
    • dn: cn=changelog5,cn=config
      changetype: add
      objectclass: top
      objectclass: extensibleObject
      cn: changelog5
      nsslapd-changelogdir: /var/lib/dirsrv/slapd-ryo/changelogdb
      nsslapd-changelogmaxage: 7d
      
    • 389 Directory 側のレプリケーション用ユーザの作成(後の PassSync のため)
    • dn: cn=sync user,cn=config
      changetype: add
      objectClass: inetorgperson
      objectClass: person
      objectClass: top
      cn: sync user
      sn: SU
      userPassword: secret
      passwordExpirationTime: 20380119031407Z
      
    • レプリケーション設定
    • dn: cn=syncreplica,cn=dc\=example\,dc\=com,cn=mapping tree,cn=config
      changetype: add
      objectclass: top
      objectclass: nsds5replica
      objectclass: extensibleObject
      cn: syncreplica
      nsds5replicaroot: dc=example,dc=com
      nsds5replicaid: 7
      nsds5replicatype: 3
      nsds5flags: 1
      nsds5ReplicaPurgeDelay: 604800
      nsds5ReplicaBindDN: cn=sync user,cn=config
      
      ここで注意が必要で、上記 ldif dn: の cn=mapping tree より上の RDN においてはスペースは許されない。スペースを入れると以下のエラーに悩まされることになる
      ERR - NSMMReplicationPlugin - agmtlist_add_callback - Can't start agreement
      
    • Sync Agreement の作成
    • dn: cn=adagreement3,cn=syncreplica,cn=dc\=example\,dc\=com,cn=mapping tree,cn=config
      changetype: add
      objectclass: top
      objectclass: nsDSWindowsReplicationAgreement
      cn: adagreement3
      nsds7WindowsReplicaSubtree: cn=Users,DC=example,DC=local
      nsds7DirectoryReplicaSubtree: ou=people,dc=example,dc=com
      nsds7NewWinUserSyncEnabled: on
      nsds7NewWinGroupSyncEnabled: on
      nsds7WindowsDomain: SIOS
      nsDS5ReplicaRoot: dc=example,dc=com
      nsDS5ReplicaHost: ad-389.example.local
      nsDS5ReplicaPort: 636
      nsDS5ReplicaBindDN: cn=replication,cn=Users,dc=example,dc=local
      nsDS5ReplicaCredentials: MySecret-123
      nsDS5ReplicaTransportInfo: SSL
      nsds5replicabindmethod: SIMPLE
      winSyncInterval: 30
      winSyncMoveAction: delete
      nsds5BeginReplicaRefresh: start
      
これでいけるんじゃないかと。

2017年10月18日水曜日

db2bak.pl の結果を知りたい

389 Directory Server の db2bak.pl の中身を見る限り、どうやらこれは
 "cn=backup, cn=tasks, cn=config" にエントリを追加するだけで、後は task プラグイン
にお任せのようだ。

エントリの追加後タスクの実行を待っていたりしないので非同期で、その結果は db2bak.pl
だけでは得ることができない。同期モードを作るべきな気がするが。
# 自分で作れってw

ちなみに db2bak.pl の終了コードは perl の DSUtil:ldapmod() の返り値と同じなので、
エントリ追加が出来たかどうかしか取れない。

じゃぁ終了判断やその結果をどうやって知るかってことになるが、errors ログファイル
を見るのが一番確実ではあるが行parseするのが面倒。

db2bak.pl を実行すると以下のように標準出力にエントリの DN が表示される。

# db2bak.pl -Z testinst -D "cn=Directory Manager" -w password
Back up directory: /var/lib/dirsrv/slapd-testinst/bak/rhds1-2017_10_18_2_15_12
Successfully added task entry "cn=backup_2017_10_18_2_15_12, cn=backup, cn=tasks, cn=config"

そのエントリを参照すると以下のよう。


dn: cn=backup_2017_10_18_2_20_7,cn=backup,cn=tasks,cn=config
objectClass: top
objectClass: extensibleObject
cn: backup_2017_10_18_2_20_7
nsarchivedir: /var/lib/dirsrv/slapd-testinst/bak/hoge
nsdatabasetype: ldbm database
nstaskcurrentitem: 0
nstasktotalitems: 1
nstasklog:: xxxxxx
  :
nstaskstatus: Backup finished.
nstaskexitcode: 0

nstasklog 属性に base64 で詳細ログが記録されてる。終了したか否かの判断は
nstaskstatus と nstaskexitcode ですれば良いっぽい。ただ、このエントリは終了後
その結果にかかわらず 2 分で消える。2 分という設定がどこにあるかわからないが、
以下で 2 分と言っている人がいた。cn=config にはそれらしき設定は無かった。

http://www.databaseusers.com/article/7985099/backup+monitor

Once a task has finished (good or bad), the entry will stay visible for 2 minutes. By viewing the nstaskstatus and nstaskexitcode attributes you can find out how far it has gone and if the task has finished successfully or with an error.
Here is an example using a persistent search filtering on nstaskexitcode so you only get a response back once the job has completed:

これをぐるぐる回して同期なスクリプトを作るか。終了後 2 分で消えるということは、
db2bak.pl 実行後にぐるぐる回す間隔を 2 分以内にすればとりあえずはなんとか消える
前に結果が取れるってことかな。

めんどくさっ
今から python で作り変えてみる。

2017年10月10日火曜日

389 Directory MemberOf Plugin は refint 不要ぽい

389 Directory の MemberOf プラグインは、あるメンバーの実エントリの DN を modrdn して書き換えると、
何もしなくても(refint overlay 使わなくても)ちゃんと groupOfNames 側の member を書き換えてくれる。

その逆の、ある groupOfNames のグループの実エントリで、グループの DN を modrdn で書き換えても
ちゃんとユーザエントリ側の memberOf を書き換えてくれた。

しかしながら groupOfNames の owner 属性は対象外っぽい。こちらは refint するしかないかも。

2017年10月7日土曜日

389 Directory Server リストア失敗 → 成功

くだらないミスだったんだけど、同じことでハマる人がいるかもしれないので役に立てばのメモ。

まぁ、タイトルは 389 Directory にしたけど本当は RHDS なんだけどね。おそらく同じだろうからまぁいいかな(違ってたらコメントで教えて下さい)。

bak2db.pl を使って、db2back.pl で取得したバックアップディレクトリからリストアを試みたが、/var/log/dirsrv/slapd-<instance>/errors には以下のエラーが。

ERR - ldbm_back_archive2ldbm - No back up "/home/ryo/rhds1-2017_10_7_3_20_46" exists.
ERR - task_restore_thread - Restore failed (error -1)

ぐぐっても情報が無いので、ソースから上記箇所を grep。すると servers/slapd/back-ldbm/archive.c に以下の箇所あり。

   48     return_value = dbversion_read(li, directory, &dbversion, &dataversion);
   49     if (return_value) {
   50         if (ENOENT == return_value) {
   51             slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_archive2ldbm", "No back up \"%s\" exists.\n",
   52                           directory);
   53             return -1;
   54         }

どうも DB のバージョンを確認するファイルが無いと(ENOENT)。バックアップディレクトリ内のファイル名から考えると
DBVERSION ってのがあるんだけど... うーーん permission も問題なし... あ、SELinux ?バックアプファイルの context を見てみる。

# ls -Z
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 DBVERSION
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 dse_index.ldif
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 dse_instance.ldif
-rw-------. dirsrv dirsrv unconfined_u:object_r:user_home_t:s0 dse.ldif
   :

あぁぁ... てことで

# chcon -R system_u:object_r:dirsrv_var_lib_t:s0 rhds1-2017_10_7_3_20_46/

これで解決しますた。

2017年10月4日水曜日

389-consle (redhat-idm-console)が ssh の X Forward で動かん→動いた

redhat-idm-console (389-console)をリモート越しに起動して手元の X で表示しようと、
試みたところ以下のエラーで起動できない。

Exception in thread "main" java.awt.HeadlessException
        at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:204)
        at java.awt.Window.(Window.java:536)
        at java.awt.Frame.(Frame.java:420)
        at java.awt.Frame.(Frame.java:385)
        at javax.swing.JFrame.(JFrame.java:189)
        at com.netscape.management.client.console.Console.(Unknown Source)
        at com.netscape.management.client.console.Console.main(Unknown Source)
Headless というのがようわからんが、/etc/java/とredhat-389-console.conf で以下の
ようにとにかくこれを外してみた。


$ diff -u /etc/java/redhat-389-console.conf.dist /etc/java/redhat-389-console.conf
--- /etc/java/redhat-389-console.conf.dist      2016-10-10 01:45:11.000000000 +0000
+++ /etc/java/redhat-389-console.conf   2017-10-04 01:44:55.026633680 +0000
@@ -1,3 +1,3 @@
 mylang=${mylang:-en}
 ADDITIONAL_JARS=${ADDITIONAL_JARS:-redhat-idm-console_$mylang.jar}
-ADDITIONAL_OPTIONS=${ADDITIONAL_OPTIONS:-"-Dprogram.name=redhat-idm-console -Djava.util.prefs.systemRoot=$HOME/.redhat-idm-console -Djava.util.prefs.userRoot=$HOME/.redhat-idm-console"}
+ADDITIONAL_OPTIONS=${ADDITIONAL_OPTIONS:-"-Dprogram.name=redhat-idm-console -Djava.util.prefs.systemRoot=$HOME/.redhat-idm-console -Djava.util.prefs.userRoot=$HOME/.redhat-idm-console -Djava.awt.headless=false"}

すると、libawt_xawt.so が無いぞと怒られ調べたらこれは Headless でない
java-1.8.0-openjdk パッケージに含まれる模様

# yum install java-1.8.0-openjdk 

しかしなんで単なる設定をいじるのにこんなに重い GUI を起動せにゃあかんのか。しかも
激重な Java。Java は Windows 以上に嫌いだわ。どの OS とも相性が悪い。当初のコンセ
プトとは大違い。クソ言語。問題なのはプログラマが多いこと。だから糞システムが量産
される。Java の世界だけで OS 作って勝手にやってりゃいいのに。こっちくんな。

2017年9月7日木曜日

/etc/sudoers をいじらずに PATH を効かせる

RHEL系の /etc/sudoers には secure_path がデフォルトで定義されている。

デフォルトの /etc/sudoers をいじりたくないのだけど、secure_path を無効にして PATH を引き継ぎたい。
そんなことを思って /etc/sudoers.d/mysetting を以下のようにしてみようとした。が visudo  に怒られた。


Defaults    secure_path =
Defaults    env_keep +=  "PATH"
%mygroup ALL = (myuser) /path/to/target*
secure_path = "" も駄目。もうちょっと考えれば何かしら解法が見つかりそうなのだが、ちょっと時間がない。ただどうしても /etc/sudoers はいじりたくない。

とりあえず今は特定のパス(/path/to/target)だけ通せば良いから、/etc/sudoers.d/mysetting を以下のようにした。全部の PATH は無理だが、今回の要件は何とかクリア。

Defaults    secure_path = /path/to/target:/sbin:/bin:/usr/sbin:/usr/bin
Defaults    env_keep +=  "PATH"
%mygroup ALL = (myuser) /path/to/target*

RHEL デフォルト /etc/sudoers の secure_path は /sbin:/bin:/usr/sbin:/usr/bin なので、それに特定のパスの「/path/to/target」を追加しただけ。


ちなみに以下も試して全 PATH 通そうとしたが駄目だった。


Defaults    secure_path -= /sbin
Defaults    secure_path -= /bin
Defaults    secure_path -=/usr/sbin/
一旦定義したパラメータを無効にする命令は無いものか...


2017年9月5日火曜日

mysql で確保されたファイル領域を OS レベルで解放したい

MySQL であるフィールドに大きなデータが入っていたとして、それを update 文で
null にしたとする。が、当然 OS 的には空きデータは増えない。

OS に空き容量を反映させたい場合は innodb_file_per_table を ON にして、
OPTIMIZE TABLE すれば良いらしい。




2017年8月16日水曜日

MySQL 5.7 の root 初期パスワード

community 版の MySQL 5.7 を RPM でインストールしたらしょっぱなからログインできない。

何と mysqld のログファイル(Fedora だと /var/lib/mysqld.log)に root の初期パスワードがあるじゃないか。
grep 'temporary password' /var/log/mysqld.log

んで、以下コマンドで早速変更。
/usr/bin/mysql_secure_installation

2017年4月20日木曜日

libvirt からの xxx-nic っていう interface について

FAQ なんだろうけどメモ。

例えば libvirt のデフォルトのネットワークの場合、virbr0 というブリッジに
virbr0-nic っていう interface がアタッチされている。
これはなんぞやといつも不思議に思っていたものの気にせず、ホストからの接続のた
めのダミー NIC か何かかと勝手に決めつけて放置していた。が、いつも link down
してるのでやっぱり気持ち悪いので調べることに。

ソース読む ability も power も無く、ググッて見つけたのがこれ。↓

https://www.redhat.com/archives/libvirt-users/2012-September/msg00038.html

| It's a workaround for kernel bug/feature. The bridge's MAC is copied
| from the first NIC attached. So if one detach all interfaces from a
| bridge and then attach just one, the bridge will lost previous MAC and
| gain a new one - just the same as the attached interface has.
|
| So if libvirt has to ensure a MAC for virtual bridge - it creates this
| dummy device (no traffic is routed through though) and just attach it to
| the virtual bridge.

うぅ、これ Red Hat の中の人が言ってるし本当だよね?
なんと MAC アドレスを固定化させるためのダミーの NIC だったとは知らなんだ。








2017年4月12日水曜日

openstack baremetal import が返ってこない。

FAQ だろうけどメモ。表題の件、解決策は pm_password の指定方法に
あった...

https://access.redhat.com/solutions/1603243

RHOSP な環境で instackenv.json を作る時に

     "pm_type": "pxe_ssh",

にした際の pm_passwod の値をよく Web で見かける "$(cat ~/.ssh/id_rsa)"
にしちゃうと openstack baremetal import が返ってこない。長らく待って
返ってきてもエラー(エラー文字列は無くしてしまった)。

上記 URL に回避策あり。秘密鍵の値をそのまま記すが、改行の部分は「\n」
で表現する。以下例。

      "pm_password": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAwCz1ReNdQg5NxOx2ZZeOA4k+UaRAb4gobdL1lv/HJnNYlcrg\n.....................................\n6AJkDzAIQwQ1s1gjSdc7SYt1FcAPB/El0U6BAiI5lnYjWxfHAyMHkOs=\n-----END RSA PRIVATE KEY-----",


うーーん、なんちゅー仕様w。ま、ありか。

2017年3月14日火曜日

virsh, NetworkManager のエラーメッセージが日本語な件

日本語環境で virsh 使ってると、エラーメッセージが日本語になってしまう。
unset LC_ALL しても LANG=C LANGUAGE=en_US.UTF-8 してもダメ。

こりゃ libvirtd が握ってるなってことで /etc/sysconfig/libvirtd に以下を追加
して libvirtd 再起動したらエラーメッセージも全部日本語になった。

LANG=en_US.UTF-8

NetworkManager も同じ。/proc/<PID>/environ で確認すると LANG が日本語になっとる。
/usr/lib/systemd/system/NetworkManager.service の [Service] セクションに下記を追加して解決。

Environment=LANG=en_US.UTF-8

2017年3月3日金曜日

wildcard.fedoraproject.org の AAAA がかっこいい件

有名な話しなんだろうけど個人的に関心したのでメモ
dnf した後に ss したら気付いた。

[ryo@localhost ~]$ host -t AAAA wildcard.fedoraproject.org.
wildcard.fedoraproject.org has IPv6 address 2604:1580:fe00:0:dead:beef:cafe:fed1
wildcard.fedoraproject.org has IPv6 address 2605:bc80:3010:600:dead:beef:cafe:fed9
wildcard.fedoraproject.org has IPv6 address 2610:28:3090:3001:dead:beef:cafe:fed3

2017年2月19日日曜日

nmcli で MAC Address 固定

USB の NIC 使ってるんだけど、nmcli で connection を ifname 固定してたら再起動の時にそれが変わってしまった。下記で MAC 固定。

nmcli con modify usbeth0 connection.interface-name '' 802-3-ethernet.mac-address 'xx:xx:xx:xx:xx:xx'

まぁここにメモらなくても nmcli con show すれば属性名から適当に設定できるけど、誰かのお役に立てればと...

connection を add する時にやっちゃう方法については、Red Hat の RHEL7 のドキュメントに丁寧に記されていた。この場合は '*' というワイルドカードが使えるのね。以下一応コピペ。


プロファイルを特定の MAC アドレスにロックするには、以下の形式のコマンドを実行します。
nmcli connection add type ethernet con-name "connection-name" ifname "*" mac 00:00:5E:00:53:00

2017年2月14日火曜日

getent のエラー文字列日本語訳

# unset LC_ALL
# LANG=C getent netgroup
Enumeration not supported on netgroup

# getent netgroup
エミュレーションは netgroup 上ではサポートされていません

いやいや、Emulation じゃなくて Enumeration だから。
今仕事中だからあとでパッチを送ることにする。

2017年1月18日水曜日

GCE でクロスリージョン+オートスケーリング 第三回

GCE でクロスリージョン+オートスケーリング 第三回

前回までで,バックエンドとなる "インスタンスグループ" の作成が完了しました。これは,2 つのリージョンを跨る負荷分散を意識し,かつ "自動スケーリング" が可能な構成になっています。今回はこの続きで,"負荷分散(ロードバランサ)" の部分を作成していきます。


"バックエンドサービス" の作成

"バックエンドサービス" は,その中に "インスタンスグループ" と関連する "バックエンド"が含まれます。またその役割には,インスタンスに対するヘルスチェックの設定やセッションパーシステンスの設定,CDN の利用有無等があります。以下,このような "バックエンドサービス" を作成していきます。

"ヘルスチェック" の作成

"ヘルスチェック" のルールを個別のオブジェクトとして作成します。この作成した "ヘルスチェック" を,後に "バックエンドサービス" にアタッチします。これは複数のバックエンドサービスからアタッチすることができます。

"ヘルスチェック" のルールには,モニタする URL のパスやポート番号,チェック間隔,タイムアウト値等が含まれます。今回はチェックする URL のみ指定し,その他はデフォルトとします。また,"ヘルスチェック" を含む "負荷分散(ロードバランサ)" サービスからのリクエストをインスタンスが受け取れるようにするため,ファイアウォールルールも設定します。

  1.  site1 への "ヘルスチェック" を作成

    site1 では,チェックする URL を /site1/index.txt にします。ヘルスチェック名を「mygce-site1-health-check」とします。
  2. $ gcloud compute http-health-checks create mygce-site1-health-check \
      --request-path "/site1/index.txt"

  3. site2 への "ヘルスチェック" を作成

    site1 では,チェックする URL を /site2/index.txt にします。ヘルスチェック名を「mygce-site2-health-check」とします。
  4. $ gcloud compute http-health-checks create mygce-site2-health-check \
      --request-path "/site2/index.txt"

  5.  "ファイアウォールルール"

    "負荷分散(ロードバランサ)" サービスは,130.211.0.0/22 がソース IP アドレスとなります(このレンジについては,ここの「ヘルスチェックのソース IP とファイアウォール ルール」節をご覧ください)。これから 80 番ポートへのアクセスを下記コマンドで許可します。ファイアウォール名は「mygce-firewall-healthcheck」としました。
  6. $ gcloud compute firewall-rules create mygce-firewall-healthcheck \
      --source-ranges '130.211.0.0/22' \
      --allow tcp:80

site1 の "バックエンドサービス" の作成

  1. site1 の "バックエンドサービス" の作成

    セッションパーシステンスを一般的によく使われる cookie ベースとし,ヘルスチェックを上記で作成した「mygce-site1-health-check」に設定した "バックエンドサービス"「mygce-site1-bs」を作成します。
  2. $ gcloud compute backend-services create mygce-site1-bs \
      --session-affinity generated_cookie \
      --http-health-checks mygce-site1-health-check \
      --global

  3. "バックエンドサービス" に "バックエンド" を追加

    「mygce-site1-bs」に,前回作成した site1 の「mygce-site1-ig-asia」「mygce-site1-ig-us」の 2 つの "バックエンド" を追加します。
  4. $ gcloud compute backend-services add-backend mygce-site1-bs \
      --instance-group mygce-site1-ig-asia \
      --instance-group-zone asia-east1-b \
      --global
    
    $ gcloud compute backend-services add-backend mygce-site1-bs \
      --instance-group mygce-site1-ig-us \
      --instance-group-zone us-east1-b \
      --global

site2 の "バックエンドサービス" の作成

  1. site2 の "バックエンドサービス" の作成

    セッションパーシステンスを一般的によく使われる cookie ベースとし,ヘルスチェックを上記で作成した「mygce-site2-health-check」に設定した "バックエンドサービス"「mygce-site2-bs」を作成します。
  2. $ gcloud compute backend-services create mygce-site2-bs \
      --session-affinity generated_cookie \
      --http-health-checks mygce-site2-health-check \
      --global

  3. "バックエンドサービス" に "バックエンド" を追加

    「mygce-site2-bs」に,前回作成した site2 の「mygce-site2-ig-asia」「mygce-site2-ig-us」の 2 つの "バックエンド" を追加します。
  4. $ gcloud compute backend-services add-backend mygce-site2-bs \
      --instance-group mygce-site2-ig-asia \
      --instance-group-zone asia-east1-b \
      --global
    
    $ gcloud compute backend-services add-backend mygce-site2-bs \
      --instance-group mygce-site2-ig-us \
      --instance-group-zone us-east1-b \
      --global

"URL マップ" の作成

URL マップは,まずその本体を作成しその後にマッピングを設定します。今回は下記のルールで URL マップを作成します
  • mygce.fatriver.net というホストへのリクエストのみ下記ルールで振り分ける
    • /site1 から始まるパス → 「mygce-site1-bs」バックエンドサービスに振り分け
    • /site2 から始まるパス → 「mygce-site2-bs」バックエンドサービスに振り分け
  • 上記以外のリクエストは「mygce-site1-bs」に振り分け。
上記ルールの URL マップを以下のように作成します。
  1. "URL マップの作成"

    ここでは "URL マップ" の名前を「mygce-url-map」としています。
  2. $ gcloud compute url-maps create mygce-url-map \
      --default-service mygce-site1-bs

  3. "Path Matcher" 及び "Host Rules" の設定

    "URL マップ" は "Path Matcher" と "Host Rules" という 2 つのコンポーネントで構成されます。"Path Matcher" は,URL のパスと "バックエンドサービス" のマッピングを定義するものです。"Host Rules" は,ホスト名と "Path Matcher" のマッピング定義です。今回はホスト名は「mygce.fastriver.net」のひとつなのでこれらを一回のコマンドで定義できます。

    なお "Path Matcher" にも名前をつける必要があり,ここでは「mygce-path-matcher」としています。
  4. $ gcloud compute url-maps add-path-matcher mygce-url-map \
      --default-service mygce-site1-bs \
      --path-matcher-name mygce-path-matcher \
      --path-rules /site1=mygce-site1-bs,/site1/*=mygce-site1-bs,/site2=mygce-site2-bs,/site2/*=mygce-site2-bs \
      --new-hosts mygce.fastriver.net

"ターゲットプロキシ" の作成

今回は HTTPS "ターゲットプロキシ" を利用します。HTTPS "ターゲットプロキシ" では SSL 終端処理を行うので,その作成の際に SSL 証明書を登録する必要があります。ちゃんとした証明書を持っていないのでオレオレを使います。関係ありませんが,よく会社でオレオレ証明書の作り方を聞かれるのですが,意外と openssl req 一発で作れることを知らない人がいるので,一応その作り方も書いておきます。

  1. オレオレ SSL 証明書の作成

    秘密鍵を mygce.key, 証明書を mygce.crt として作成しています。作成した後,秘密鍵は暗号化されない生の状態にする必要があります。そのファイル名を mygce-nopass.key としています。
  2. $ openssl req -x509 -newkey rsa:2048 -keyout mygce.key -out mygce.crt
    $ openssl rsa -in mygce.key -out mygce-nopass.key # ← 秘密鍵のパスフレーズを解きます

  3. "SSL 証明書リソース" の登録

    上記で作成した SSL 証明書「mygce.crt」と秘密鍵「mygce.key」を "SSL 証明書リソース" として登録します。その名前を「mygce-cert」としています。
  4. $ gcloud compute ssl-certificates create mygce-cert \
      --certificate mygce.crt \
      --private-key mygce-nopass.key

  5. "ターゲットプロキシ" の作成

    上記で作成した "SSL 証明書リソース"「mygce-cert」と,"URL マップ" 「mygce-url-map」を使い "ターゲットプロキシ"「mygce-target-proxy」を作成します。
  6. $ gcloud compute target-https-proxies create mygce-target-proxy \
      --ssl-certificate mygce-cert \
      --url-map mygce-url-map

"グローバル転送ルール" の作成

最後に,フロントエンドの役割を受け持つ "グローバル転送ルール" を作成します。これは,待ち受けポートの定義やグローバル IP アドレスの保有有無等を定義します。"グローバル転送ルール" はリージョンを意識しません。
  • "グローバル転送ルール"の作成

    "グローバル転送ルール"の名前を「mygce-forwarding-rule」とします。今回は HTTPS(443) ポートでのみ待ち受けます。
  • $ gcloud compute forwarding-rules create mygce-forwarding-rule \
      --target-https-proxy mygce-target-proxy \
      --global-address \
      --global \
      --ports 443

上記コマンドを実行すると,付与されたグローバル IP アドレスが表示されますので,それを A レコード(!! CNAMEでない)で DNS サーバに登録すれば完成です(とりあえずの確認であれば hosts ファイルに登録すれば十分です)。

今回私は,mygce.fastriver.net というホスト名で A レコードを登録しました。そして以下の URL にブラウザからアクセスしてみます。
  • https://mygce.fastriver.net/site1/index.txt
  • https://mygce.fastriver.net/site2/index.txt
すると,前回でそれぞれの index.txt の中に記した「site1」または「site2」の文字がブラウザに表示されるはずです。セッションパーシステンスを確認したい場合は,一旦ブラウザを終了して新たな cookie でアクセスしてみるのも良いでしょう。

というわけで,これでクロスリージョンの負荷分散かつオートスケーリングな Web サーバが出来上がりました。今回の例は本当に簡易的な構成ですので,実際の運用ではもっと複雑な要件があり,複雑な設定をすると思います。その際は gcloud コマンドのヘルプやら Google が提供するドキュメント等を参考にしてください。

ではさようなら。

GCE でクロスリージョン+オートスケーリング 第三回

2017年1月17日火曜日

GCE でクロスリージョン+オートスケーリング 第一回

GCE でクロスリージョン+オートスケーリング 第一回

GCE ってすごいかも

Google Compute Engine(GCE) でグローバル IP アドレスを確保する際,大きな特徴としてリージョンを指定する・しないの選択が可能です("グローバル転送ルール" (後述) のときのみ)。リージョン指定しなくて良いってことは,例えばあるリージョンが戦争とかで壊滅状態になったときに何もしなくても同一 IP アドレスで別のリージョンで運用継続できるってこと?

だとすると,個人的にはこりゃすごいと関心してしまいます(違ってたらすみません,ご指摘ください)。オンプレだとマルチホーミングして AS 取得して BGP で... などとしていたことが,いとも簡単にコマンドやブラウザから椅子に座りながらチョイチョイで設定可能です。

ちょっと外れますが,おそらく AWS だとこのようなリージョンを超えた Elastic IP address の設定は出来ないと思われます。Multi AZ は可能ですが,disaster 対策や冗長化には Endpoints の CNAME で対処していると私は理解しています(間違ってたらごめんなさい, ご指摘いただけると助かります)。

また,この仕組みにより GCE では cross regional な負荷分散も可能にします。つまり異なるリージョンにある末端インスタンスノードにリクエストを分散できるようです。

これらについては,おそらく「今更」感バリバリと思いますが個人的には今更感動しています。そんなこんなで,仕事柄 AWS で Web システムを構築することが多い私が,そこでよくやる基本的なオートスケーリングなサーバ構成を GCE でも作ってみようか,しかもクロスリージョンで! という気になり,ちょっとやり方をメモしようとこれを書くことにしました(基本中の基本なことになっちゃいますが...)。

今回作るものの概要

こんな感じのものを作る

というわけで本当に基本的なものですが,今回は以下イメージのような基礎的な Web サーバのシステムを作ってみます。

よくある Web サーバシステムの図

よくある,DMZ に LB がいて,それが 2 本の足を持っていてその下の独立したプライベートネットワーク上に Web サーバが複数台いるというやつです。LB がその Web サーバ達にリクエストを振り分けるって感じです。

これを Google Compute Engine で表現してみます。末端ノードの Web サーバは,固定台数でなくオートスケーリングにします。GCE はインフラ的なネットワーク設計をある程度意識しなくて良いので下記のような感じです。

GCE ではこんな感じの図

必要な GCE 要素の概要

  • ネットワーク

    あまり意識せず 「default」のネットワークを使います。自動的に cross region なサブネットに切られているはずです。AWS とは根本的に考え方が違います。個人的には GCE の方が未来を感じます。

  • "負荷分散(Load Balancer)"

    GCE のロードバランサは AWS の ELB と違って,さぁロードバランサを作るぞ!って感じではなく,以下のような要素を組み立てていきます。

    • "グローバル転送ルール"

      待受の IP アドレスとポートを定義する(BIG-IP で言えば Virtual Server の部分か)。この IP アドレスは前述のリージョンを指定しないものを割り当てることができる。

    • "ターゲットプロキシ"

      その名の通りここは Reverse Proxy の役割だろう。どうもクライアントからの直接のリクエストは一旦ここで受け取ってるっぽい。SSL Termination もここでやる。その後リクエストを解釈して X-Forwarded-For 等の Proxy 用の HTTP ヘッダを追加している。

    • "URL マップ"

      URL により 振り先定義するところ(Apache とか NGINX とかで言えば、Location による振り分け)。

    • "バックエンドサービス"

      末端のインスタンスグループを取りまとめているところ。BIG-IP で言えば pool だろうか。ヘルスチェックや persistence はここでやってる。

  • "インスタンスグループ"

    インスタンスグループは,その名の通りインスタンスの集まりです。"自動スケーリング" を利用したい場合はここで定義できます。"インスタンスグループ" に含まれる各インスタンスの雛形は "インスタンステンプレート" で定義します。その中にインスタンスの "イメージ" も含まれ、これは以下の手順で作成することになります。

    1. "公開イメージ" から "ディスク" 作成
    2. 作成した "ディスク" をブートディスクとしてアタッチしてインスタンスを生成
    3. OS にログインしてお好きなようにカスタマイズ
    4. "ディスク" を消さないようにインスタンス削除
    5. 孤立したディスクから "イメージ" 作成

というわけで今回はここまでとします。次回は具体的に gcloud コマンドを使って実装していくことにします。

GCE でクロスリージョン+オートスケーリング 第一回

GCE でクロスリージョン+オートスケーリング 第二回

GCE でクロスリージョン+オートスケーリング 第二回

前回では,GCE でこんなものを作ってみようかな,ということについての概要を書きました。今回はそれを具体的に作っていきます。

構成



上図は,今回作成する構成を簡単に表したものです。"負荷分散(ロードバランサ)" で HTTPS(443)ポートでリクエストを受け付け,"ターゲットプロキシ" で SSL 終端処理を行います。その後 "URLマップ" で /site1 という URL と /site2 という URL へのリクエストを解釈して,それぞれ異なる "バックエンドサービス" に振り分けます。

"インスタンスグループ"はそれぞれの "バックエンドサービス" 内に 2 つづつ用意し,異なるリージョンに配置します。これはリージョンを跨ぐ負荷分散を実現するための準備です。

"インスタンスグループ" 内のインスタンスは "自動スケーリング" によりスケールイン/アウトを繰り返すよう設定します。この場合は "管理対象インスタンスグループ" として作成します。このため,インスタンスの雛形を定義する "イメージ" を作成し,さらにその起動設定を "インスタンステンプレート" で定義する必要があります。

では,まず "イメージ" の作成から具体的にやっていきましょう。今回は "負荷分散(ロードバランサ)" の "バックエンド" となる "インスタンスグループ" の作成まで行うこととします。

なお,以降 GCE の Web GUI コンソールは使わず,全て gcloud コマンドで行います。gcloud コマンドの操作方法についてはここでは触れません。gcloud からの認証(gcloud auth login)やプロジェクトの作成,およびデフォルトのプロジェクト設定についても既に行っていることとします。

また,GCE に作るオブジェクトの名前は全て「mygce-」というプレフィクスをつけたいと思います。

"イメージ" の作成まで

まず,インスタンスの雛形となる "イメージ" を作成します。今回は GCP が公開している CentOS 7 の "イメージ" をベースとし,その上に Apache (httpd)が稼働するようにします。また,前出の図のように機能が異なる Web サーバに URL で振り分けを行いますので,2 つの "イメージ" を作成します。今後、これらのサイトを便宜上「site1」「site2」と呼びます。

site1 の "イメージ" の作成

site1 の "イメージ" は,「"ディスク" 作成」→「インスタンス起動」→「Apache等インストール/設定」→「インスタンスを削除して "ディスク" 解放」→「"イメージ" 作成」といった手順で作成します。
  1. "公開イメージ" から "ディスク" 作成

    CentOS7 の "公開イメージ" から名前が「mygce-site1-disk」という "ディスク" を作成します。"ゾーン" は任意のものを設定しています。
  2. $ gcloud compute disks create mygce-site1-disk \
      --image-family=centos-7 \
      --image-project=centos-cloud \
      --zone asia-east1-b

  3. 作成した "ディスク" をブートディスクとしてアタッチしてインスタンスを生成

    1 で作成した "ディスク" からインスタンスを立ち上げます。この後,これにログインして好みの設定にしていきます。"ゾーン" は任意です。--metadata で「ryo」というユーザでログインする際に必要な ssh 公開鍵(~/.ssh/id_rsa.pub)を渡しています。インスタンス名を「mygce-site1-tmp-instance」としています。
  4. # Windows の人は ssh 鍵の渡し方を適当に工夫してください.
    # --metadata-from-file なんてオプションもありますよ。
    $ gcloud compute instances create mygce-site1-tmp-instance \
      --disk name=mygce-site1-disk,boot=yes \
      --metadata "ssh-keys=ryo:$(cat ~/.ssh/id_rsa.pub)" \
      --zone asia-east1-b

  5. OS にログインしてカスタマイズ

    上記 2 の実行が成功すると,作成されたインスタンスの IP アドレスが表示されます(下記では xxx.xxx.xxx.xxx で表示しています)。ssh でそれにログインします
  6. $ ssh ryo@xxx.xxx.xxx.xxx
    ログイン後,まず httpd をインストールします。また,今回は URL によりアクセスするサイトを振り分けますので,どちらのサーバにアクセスしたかブラウザからわかるようにします。Apache の DocumentRoot ディレクトリ以下に「site1」とだけ記した index.txt というファイルを配置します。
    [ryo@mygce-site1-tmp-instance]$ sudo yum install httpd -y
    [ryo@mygce-site1-tmp-instance]$ sudo mkdir /var/www/html/site1
    [ryo@mygce-site1-tmp-instance]$ echo "site1" | sudo tee /var/www/html/site1/index.txt
    [ryo@mygce-site1-tmp-instance]$ sudo systemctl enable httpd
    [ryo@mygce-site1-tmp-instance]$ exit

  7. "ディスク" を消さないようにインスタンス削除

    上記 2 で作成したインスタンス「mygce-site1-tmp-instance」を削除します。これは,インスタンスに関連付けられたディスクからはイメージの作成ができないためです。なお下記コマンド例では -q で削除の確認を行わないようにしていますのでご注意ください。
  8. $ gcloud compute instances delete mygce-site1-tmp-instance --zone asia-east1-b -q

  9. "ディスク" から "イメージ" 作成

    下記コマンドで,上記 1, 3 で作成/編集した "ディスク"「mygce-site1-disk」から「mygce-site1-image」という名前の "イメージ" を作成します。この際,--family というオプションが必要になりますが,これは任意の文字列を指定します。ここでは「mygce-site1-image-family」としました。
  10. $ gcloud compute images create mygce-site1-image \
      --source-disk-zone=asia-east1-b \
      --source-disk mygce-site1-disk \
      --family mygce-site1-image-family


site2 の "イメージ" の作成

site2 の "イメージ" は「site1 の "イメージ" から "ディスク" 作成」→「インスタンス起動」→「/var/www/html/index.txt の内容を変更」→「インスタンス削除」→「"イメージ" 作成」という手順で行います。
  1. site1 の "イメージ" から "ディスク" 作成

    これまでに作成した 1 つ目の "イメージ" を元に下記コマンドで "ディスク" 「mygce-site2-disk」を作成します。この際,--image-family オプションに上記 5 で指定した「mygce-site1-image-family」与えます。
  2. $ gcloud compute disks create mygce-site2-disk \
      --image-family=mygce-site1-image-family \
      --zone=asia-east1-b

  3. 作成した "ディスク" をブートディスクとしてアタッチしてインスタンスを生成

    上記 1 で作成した "ディスク"「mygce-site2-disk」からインスタンスを生成します。ssh 鍵は 1 つ目のインスタンスを作成したときと同じように指定します。インスタンス名は「mygce-site2-tmp-instance」としました。
  4. $ gcloud compute instances create mygce-site2-tmp-instance \
      --disk name=mygce-site2-disk,boot=yes \
      --metadata "ssh-keys=ryo:$(cat ~/.ssh/id_rsa.pub)" \
      --zone asia-east1-b

  5. OS にログインしてカスタマイズ

    上記 2 の実行が成功すると,作成されたインスタンスの IP アドレスが表示されます(下記では xxx.xxx.xxx.xxx で表示しています)。ssh でそれにログインします。
  6. $ ssh ryo@xxx.xxx.xxx.xxx
    ログイン後,Apache の DocumentRoot ディレクトリ下にある index.txt の内容を「site2」に変更します。
    [ryo@mygce-site2-tmp-instance]$ sudo mkdir /var/www/html/site2
    [ryo@mygce-site2-tmp-instance]$ echo "site2"  | sudo tee /var/www/html/site2/index.txt
    [ryo@mygce-site2-tmp-instance]$ sudo systemctl enable httpd
    [ryo@mygce-site2-tmp-instance]$ exit

  7. "ディスク" を消さないようにインスタンス削除

    上記 2 で作成したインスタンス「mygce-site2-tmp-instance」を削除します。これは,インスタンスに関連付けられた "ディスク" からは "イメージ" の作成ができないためです。なお下記コマンド例では -q で削除の確認を行わないようにしていますのでご注意ください。
  8. $ gcloud compute instances delete mygce-site2-tmp-instance --zone asia-east1-b -q

  9. ディスクからイメージ作成

    下記コマンドで,上記 1, 3 で作成/編集した "ディスク"「mygce-site2-disk」から「mygce-site2-image」という名前の "イメージ" を作成します。この際,--family というオプションが必要になりますが,これは任意の文字列を指定します。ここでは「mygce-site2-image-family」としました。
  10. $ gcloud compute images create mygce-site2-image \
      --source-disk-zone=asia-east1-b \
      --source-disk mygce-site2-disk \
      --family mygce-site2-image-family

"インスタンスグループ" の作成まで

"負荷分散(ロードバランサ)" の "バックエンド" となる "インスタンスグループ" を作成します。今回は,米国と日本の 2 つのリージョンに跨る負荷分散を行いますので,"インスタンスグループ" を site1, site2 のそれぞれで 2 つのリージョンに作成します。

site1 の "インスタンスグループ" の作成

  1. site1 の "インスタンステンプレート" の作成

    "インスタンスグループ" を作成する前に "インスタンステンプレート" 「mygce-site1-template」を作成します。この際,マシンタイプを小さな g1-small で指定します。"イメージ" の源泉は上記で作成した「mygce-site1-image」です。ログインできるように ssh の公開鍵も登録します。
  2. $ gcloud compute instance-templates create mygce-site1-template \
      --machine-type g1-small \
      --image-family mygce-site1-image-family \
      --metadata "ssh-keys=ryo:$(cat ~/.ssh/id_rsa.pub)"

  3. 日本のリージョンに site1 の "インスタンスグループ" を作成

    まず日本リージョンの "ゾーン"「asia-east1-b」に「mygce-site1-ig-asia」という "インスタンスグループ" を作成します。"インスタンステンプレート" は上記 1 で作成した「mygce-site1-template」を指定します。
  4. $ gcloud compute instance-groups managed create mygce-site1-ig-asia \
      --size 1 \
      --template mygce-site1-template \
      --zone asia-east1-b

  5. "オートスケーリング" の設定

    "インスタンスグループ"「mygce-site1-ig-asia」に "自動スケーリング" を設定します。ここでは,最小インスタンス数 1, 最大インスタンス数 3, スケールアウトの CPU 閾値を 80% とします。
  6. $ gcloud compute instance-groups managed set-autoscaling mygce-site1-ig-asia \
      --max-num-replicas 3 \
      --min-num-replicas 1 \
      --target-cpu-utilization 0.8 \
      --scale-based-on-cpu \
      --zone asia-east1-b

  7. 米国のリージョンに site1 の "インスタンスグループ" を作成

    米国リージョンの "ゾーン"「us-east1-b」に「mygce-site1-ig-us」という "インスタンスグループ" を作成します。"インスタンステンプレート" は上記 1 で作成した「mygce-site1-template」を指定します。
  8. $ gcloud compute instance-groups managed create mygce-site1-ig-us \
      --size 1 \
      --template mygce-site1-template \
      --zone us-east1-b

  9. "オートスケーリング" の設定

    "インスタンスグループ"「mygce-site1-ig-us」に "自動スケーリング" を設定します。ここでは,最小インスタンス数 1, 最大インスタンス数 3, スケールアウトの CPU 閾値を 80% とします。
  10. $ gcloud compute instance-groups managed set-autoscaling mygce-site1-ig-us \
      --max-num-replicas 3 \
      --min-num-replicas 1 \
      --target-cpu-utilization 0.8 \
      --scale-based-on-cpu \
      --zone us-east1-b

site2 の "インスタンスグループ" の作成

site2 のインスタンスグループの作成は site1 とほぼ同じですが,以下一応コマンドを全て記しておきます。
  1. site2 の "インスタンステンプレート" の作成

    "インスタンスグループ" を作成する前に "インスタンステンプレート" 「mygce-site2-template」を作成します。この際,マシンタイプを小さな g1-small で指定します。"イメージ" の源泉は上記で作成した「mygce-site2-image-family」です。ログインできるように ssh の公開鍵も登録します。
  2. $ gcloud compute instance-templates create mygce-site2-template \
      --machine-type g1-small \
      --image-family mygce-site2-image-family \
      --metadata "ssh-keys=ryo:$(cat ~/.ssh/id_rsa.pub)"

  3. 日本のリージョンに site2 の "インスタンスグループ" を作成

    まず日本リージョンの "ゾーン"「asia-east1-b」に「mygce-site2-ig-asia」という "インスタンスグループ" を作成します。"インスタンステンプレート" は上記 1 で作成した「mygce-site2-template」を指定します。
  4. $ gcloud compute instance-groups managed create mygce-site2-ig-asia \
      --size 1 \
      --template mygce-site2-template \
      --zone asia-east1-b

  5. "オートスケーリング" の設定

    "インスタンスグループ"「mygce-site2-ig-asia」に "自動スケーリング" を設定します。ここでは,最小インスタンス数 1, 最大インスタンス数 3, スケールアウトの CPU 閾値を 80% とします。
  6. $ gcloud compute instance-groups managed set-autoscaling mygce-site2-ig-asia \
      --max-num-replicas 3 \
      --min-num-replicas 1 \
      --target-cpu-utilization 0.8 \
      --scale-based-on-cpu \
      --zone asia-east1-b

  7. 米国のリージョンに site2 の "インスタンスグループ" を作成

    米国リージョンの "ゾーン"「us-east1-b」に「mygce-site2-ig-us」という "インスタンスグループ" を作成します。"インスタンステンプレート" は上記 1 で作成した「mygce-site2-template」を指定します。
  8. $ gcloud compute instance-groups managed create mygce-site2-ig-us \
      --size 1 \
      --template mygce-site2-template \
      --zone us-east1-b

  9. "オートスケーリング" の設定

    "インスタンスグループ"「mygce-site2-ig-us」に "自動スケーリング" を設定します。ここでは,最小インスタンス数 1, 最大インスタンス数 3, スケールアウトの CPU 閾値を 80% とします。
    $ gcloud compute instance-groups managed set-autoscaling mygce-site2-ig-us \
      --max-num-replicas 3 \
      --min-num-replicas 1 \
      --target-cpu-utilization 0.8 \
      --scale-based-on-cpu \
      --zone us-east1-b

これでリージョンを跨ぐ負荷分散を考慮した 2 つのサイトの "インスタンスグループ" を作成することができました。次回はこの続きで,"負荷分散(ロードバランサ)" の部分を作成していきます。

GCE でクロスリージョン+オートスケーリング 第二回

2017年1月9日月曜日

dnf group list で隠れグループ表示

Fedora の dnf で group list しても表示されないグループがある。隠れグループなの?

dnf group list -v hidden 

これで表示可能。

2017年1月4日水曜日

grub2 ブートオーダの Fedora 流変更メモ

以下私の環境の場合

#メニューエントリの取得 (コマンド無いんやね...)
egrep ^menuentry /etc/grub2-efi.cfg

#ブートデフォルトの設定 (/etc/default/grub に GRUB_DEFAULT=saved確認)
grub2-set-default 'Hoge Hoge Fuga Fuga'

#確認
grub2-editenv list