CloudFormationを使いredmineのインスタンスを起動する
おはようございます。インフラの宮下です。 社内向けredmineが古いのでリプレイスを検討しています。 できるだけ手間をかけずに検証環境を用意したいと思い、AWSのcloudformationを使って redmineを用意してみました。 目次 はじめに CloudFormationでインスタンスを作成する インスタンスが起動してからの設定 はじめに 現在稼働しているredmine環境が物理サーバにバージョンがRedmine 1.1.2.stable (MySQL)ととても古いので最終的には入替まで実施したいと思います。 CloudFormationでインスタンスを作成する ManagementConsoleからCloudformationの画面を開きます。 「Create Stack」で新規作成を開始します。 ・Name→管理しやすい名前を自由につける。 ・Template→Use sample templateの中のSingleInstanceSamplesの中から「Redmine Project Management System」を選ぶ。 ※検証環境なので今回は最小化された構成で構築します 「Next Step」で次に進みます。 Specify Parametersにそれぞれ値を入れていくのですが、デフォルトではkeyを指定する事ができませんでした。 という事で一旦「Back」で戻ります。 amazonが公開している下記のテンプレートをローカルPCに保存します。 https://s3.amazonaws.com/cloudformation-templates-us-east-1/Redmine_Single_Instance.template サンプルとの違いは、KeyNameの定義が入っているだけですのでSSHログインしないというのであれば この作業は不要です。 [shell](8行目) “KeyName”: { “Description” : “Name of an existing EC2 KeyPair to enable SSH access to the instances”, “Type”: “String”, “MinLength”: “1”, “MaxLength”: “255”, “AllowedPattern” : “[\\x20-\\x7E]*”, “ConstraintDescription” : “can contain only ASCII characters....SSHでforced-commands-onlyを使ってVIPを付けてみる
おはようございます。インフラの宮下です。 今回は端末機からサーバの仮想IPを付けたり削除する時のSSH設定に関する手順です。 MHAの内部でIPをfailoverする所をお手製で実施するイメージです。 SSH接続でroot権限を実行する方法としては、 ・rootで公開鍵認証が出来るようにする。 ・ログインユーザがsudo出来るようにしてrootにスイッチする。 ・rootで特定のコマンドだけ実施出来るようにする。 の3通りありますが、今回はセキュリティレベルがそんなに変わらない3番目の方法を適用したいと思います。 既にsudo出来る環境なら良かったのですが、sudoできない環境なのでforced-commands-onlyを使用します。 作業環境は以下の通りです。 接続元のOS:SunOS test 5.10 Generic_147440-19 sun4v sparc sun4v →端末機と呼びます 接続先のOS:Red Hat Enterprise Linux Server release 6.2 (Santiago) →サーバ呼びます 今時珍しいsolarisが端末と言う事でレトロ感満載の環境と言う事はお察し下さい。 (端末機の設定) ・ログインするユーザの公開鍵を作成します。コマンド毎に鍵を分けるので2個用意します。 [shell]# ssh-keygen -t rsa -N "" -f ~/.ssh/ipadd_command 公開/非公開 rsa 鍵のペアを生成しています。 識別情報が /export/home/test/.ssh/ipadd_command に保存されました。 公開鍵が /export/home/test/.ssh/ipadd_command.pub に保存されました。 鍵のフィンガープリント: 80:1e:4f:8b:2a:0d:22:fb:e2:c7:22:75:70:ef:db:a2 test@test...要素が1つしかない連想配列のネストを解消する
WordPress関数(特に$wpdbクラスなどに多い。get_results()メソッドでDBの値をとって来たときなど)を使っていて、戻り値の配列が一つしか要素持ってないのに連想配列になっていたりする場合、値を取り出すときにネストしたループ処理を書くケースが結構ある。 以前からコード的に冗長で非効率だよなぁ…と思っていて、今回改善方法を見出してスッキリしたので、ここにTIPSとして残しておこうかと。 $array = array( array( 'key_1' => 'value_1', 'key_2' => 'value_2', ), ); foreach ($array as $nested_array) { foreach ($nested_array as $key => $value) { echo 'array["' . $key . '"] => "' . $value . '"<br />'; } } 今まではこんな感じに(無駄ではないのだが、効率的ではない)foreachループを連想配列の入れ子分回して値取ってた…。 で、この連想配列とループのネストを解消してシンプルに処理を書けないものか…とPHPのarray関数を色々と試してみた。array_reduce()とかarray_walk()とかあんまり使わない関数で、独自にネスト解消用の関数組んでもできるんだが、別途独自関数用意しなきゃならなくてまるでスマートでない…。なんかスパっと1ラインで解決できないかと試行錯誤してみたところ、ありました! array_shift()で先頭要素取得して元の配列変数を上書きしてしまえばいいのです。 $array = array_shift($array); たったこれだけ(笑) でも、これだけだと配列の要素数が1つ以上でも上書きしてしまうので、要素数の判定を入れておく。 $array = (count($array) == 1) ?...InternetExplorer11で変更されたUserAgent書式に対応する
今まで問題なく稼動していたとあるシステムにて、InternetExplorer11(以下IE11)のブラウザにて不具合が発生する旨の報告を受けて調べたところ、IE11ではユーザーエージェントの書式が変更になっていて、ブラウザ判定処理が「不明なブラウザ」として処理されていたことがわかった。 今までユーザーエージェントのブラウザバージョントークン(UAの"MSIE 9.0"とか書いてある部分)でIEブラウザの判定とIEバージョンを取得していたのだが、IE11からはこのブラウザバージョントークンがなくなってしまい、新たに"rv"というリビジョントークンが設けられてました(※IE11標準ブラウザモード)。 今後IE11を含めてユニークにIEを判定するには、ブラウザエンジンであるトライデントトークン(UAの"Trident/7.0"とか書いてある部分)の存在確認もOR条件で判定しないといけなくなった。 IE11のUserAgent [ブラウザモード:標準] Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko [ブラウザモード:互換表示] Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0) 問題なのが、IEの互換表示モードだ。IEの互換表示モードはIE9から導入された機能だが、このモードにすると現状の全てのIEにおいてUAのブラウザバージョントークンがIE7となってしまう。互換表示の際についても正確にIE11と判定させるには、まずトライデントトークンを先に判定して、トライデントのバージョンが7.0以上だったらIE11として判定しリビジョントークンからブラウザバージョンを取得し、それ以外はブラウザバージョントークンからバージョンを取得するという処理にする必要がある。さらにIE11より下位の互換表示モードをもつIE9とIE10用の処理も必要だ。 また、IE7以下はトライデントトークンを持っていないので、IE7用の判定処理も別途必要となる…(いやはや、まるで嫌がらせのような仕様だな…)。 試しにこのDEVLABで利用している独自のクライアントデバイス判定処理(PHP)で、IE11にも対応した判定処理に修正してみた。 まずは、今までのIE判定処理内容。 [php] $ua = $_SERVER[‘HTTP_USER_AGENT’]; $results[‘browser’] = ‘’; $results[‘version’] = ‘’; if (preg_match(’/(MSIE \d{1,}?(.\d{1,}?){1,}?;)/’, $ua, $mtcs)) { $results[‘browser’] = ‘msie’; list(, $vstr) = explode(’ ‘, str_replace(’;’, ‘’, $mtcs[0])); $results[‘version’] = $vstr; } [/php]...Android アプリに設定されたパーミッションを取得する
もしmanifestに設定されていないパーミッションが必要な機能を使うと無慈悲なSecurityExceptionが発生します。 それはもう、catch節をスルーするくらい無慈悲です。 このExceptionが発生するという事は、manifestとコードが不一致だということなので、コード直せボケ! なのかもしれませんが、やはりコード内でパーミッションをチェックして条件分岐したい事もあるものです。 例えばライブラリとして公開する場合とか。 そんなわけで、パーミッションのリストを取得するメソッドと、お目当てのパーミッションがmanifestに存在するのか確認するメソッドをお届けします。 [code lang="java" light="true"] /** * 指定されたパーミッションがmanifestに記載されているかどうか確認します。 * * @param checkPermission 調査するパーミッション * @param context コンテキスト * @return true:記載されている /false:記載されていない */ public boolean hasPermission(String checkPermission, Context context) { if (checkPermission == null || context == null) { // 引数が渡されていないケース return false; } String[] requestedPermissions = getPermissionList(context); if (requestedPermissions == null) { // manifestに一件もpermissionが設定されていないケース return false; } for (String str : requestedPermissions) { if (str....GitHubでpush時にAWS OpsWorksで自動デプロイする方法
開発の平形です。 今日は、GitHubでpush時にAWS OpsWorksで自動デプロイする方法をお教えします。 OpsWorksはAWSで提供されているデプロイのサービスです。 *OpsWorksについては、こちらのサイトが詳しいです。 この話は、OpsWorksにスタックとレイヤとインスタンスが存在する前提です。 OpsWorks自体、最近触ったばかりですが、 デプロイがすごく簡単にできるという事はよくわかりました。 でも、欲張りな僕は、もっと自動化できないのかな?と思ったのです。 普段、ソースはGitHubでバージョン管理しているので、 GitHubにpushしたら同時にデプロイできないのかな?と。 そしたら、ビックリするほど簡単に実現できました。 GitHub側で設定が可能です。 アプリケーションのリポジトリのページの「Settings」 「Service Hooks」 AWS OpsWorks 以下の項目は全て必須なので、全部入力します。 ここで、OpsWorks側の情報が必要になります。 まずは、Stack Idですが、一見これがわかるところが、AWS Managed Consoleの画面上にはありません。 手っ取り早くこれを確認する方法はStackの画面のURLをみる事です。 次にApp Idですが、同じくOpsWorksの画面で、「Apps」=>「アプリケーション名」をクリック OpsWorks IDがApp Idです。 Branch Nameはリポジトリのデプロイしたいブランチ名を指定。 AWSのアクセスキーとシークレットキーを入力し、Update settingsをポチっとします。 あとは、該当ブランチにpushするだけ! これで自動的にOpsWorksのデプロイが走ります。 僕はこれに感動しました! ただ、欲張りな僕はまたまた思ったのですね。 OpsWorksではスタックを本番環境とステージング環境と分けて運用してるとします。 そうすると、 releaseブランチはステージング masterブランチは本番 にそれぞれ自動デプロイできたらいいなー、と。 しかし、一つのリポジトリにつき、一つのスタックの設定しかできないんですよね。 という事で「できない」という事がわかり、取り乱しました。 まあ実際の運用で、masterのpushしただけでいきなりデプロイするのもトラブルの元になりそうだし、 そういうもんなんだ。って自分に言い聞かせて落ち着きを取り戻しました。 それでも便利には変わりないですけど。 あなたのデプロイライフがもっと充実しますように。 以上、平形がお届けしました。...redisのソースインストール(chef-solo)
こんにちは。opsのほうの小宮です。 redisのソースインストールをご依頼いただきCHEF-SOLOったのでその記録をのこしておきます。 ★要件 バージョンについては2.8.4でお願いします。(2014/1時点で最新のソース) ★以下作業 ・rpmで入るバージョンの確認(※同環境のサーバでyumで確認) redis.x86_64 0:2.4.10-1.el6 ※要件に合わないためソースインストールする必要がある ・chef-soloの下準備 [shell]$ ssh-copy-id -i ~/.ssh/id_dsa.pub server2 $ ssh-copy-id -i ~/.ssh/id_dsa.pub server1 $ knife solo prepare server1 $ knife solo prepare server2[/shell] ・role作成 [shell]$ vi roles/rankingAPI.json { “name”:“rankingAPI”, “chef_type”: “role”, “json_class”:“Chef::Role”, “default_attributes”:{ “base_setting”: { “swappiness”: “0”, “tcp_tw_reuse”: “0”, “tcp_tw_recycle”: “0”, “tcp_fin_timeout”: “10”, “tcp_max_syn_backlog”: “8192”, “somaxconn”: “8192”, “ntpserver1”: “ntp....gitでクローンと同時にサブモジュールを初期化、アップデートする
こんにちは。 開発の平形です。 初投稿になります。 Gitでcloneした後に、何かが足りなくてうまく動かない事がよくあります。 そして気づくのです。 あ、submoduleをクローンしてねーじゃん! ※submoduleについてはこちらの記事が参考になります。 このパターン何回目だよ! と自分が嫌になってしまいます。 そしていつも、 git clone git://github.com/foo/bar.git git cd bar git submodule update --init --recursive といったお決まり作業をする訳です。 でもついつい忘れてしまうんですよね。 で、調べてみるとちゃんとあるんですね。 git clone --recursive git://github.com/foo/bar.git これで、クローンと同時にサブモジュールもクローンされます。 通常のクローンと使い分ける必要も特にないので、これからはこれを使っていこうと思います。 読んでいただいてありがとうございました。 まだまだ、寒い日が続いておりますが、お体にご自愛くださいませ。 参考にしたページ http://stackoverflow.com/questions/3796927/how-to-git-clone-including-submodules...cpuコア数に応じたrps_cpusに入れる値の計算方法
こんにちは。OPSのほうの小宮です。 cpuコア数に応じたrps_cpusに入れる値の計算方法です。 ネットワークの割り込み処理を複数コアに分散したいという要望がありまして。(特にキャッシュサーバ) できる人に頼って、ここ↓まで頑張ってもらいました。 [shell]# core=1 # echo “obase=16; ibase=10; $(( 2 ** ${core})) -1” | bc | tr ‘[A-Z]’ ‘[a-z]’ 1 # core=2 # echo “obase=16; ibase=10; $(( 2 ** ${core})) -1” | bc | tr ‘[A-Z]’ ‘[a-z]’ 3 # core=4 # echo “obase=16; ibase=10; $(( 2 ** ${core})) -1” | bc | tr ‘[A-Z]’ ‘[a-z]’ f # core=5 # echo “obase=16; ibase=10; $(( 2 ** ${core})) -1” | bc | tr ‘[A-Z]’ ‘[a-z]’ 1f[/shell]...Mondo Rescue使ってみました(その2)
おはようございます。インフラの宮下です。 前回「Mondo Rescue」で取得したバックアップデータを使用して、レストアするまでを紹介します。 目次 はじめに レストア実施 参考サイト はじめに バックアップをとるまでは実行しますが、物理環境だとレストアまではなかなか検証する環境が無いので最初にしっかりとレストアしておくのが賢明だと思います。クラウドはその辺いいですね~♪ バックアップをNFS先に出力した方がMondo Rescueぽいですが、今回はネットワーク環境の都合と作業時間が限られていた為に ローカル出力してDVDメディアからレストアする方法を選択しました。 前回作成したしたisoイメージをDVDに書き込んでおきます。 DVDへの書き込みですが、私は昔からDeepBurnerを愛用しています。 DeepBurner レストア実施 DVDメディアを挿入して、サーバを起動します。 mondoのOSが立ち上がってきたら「boot:」プロンプトが出てきますので下の中から方式を選択します。 nuke全自動でリストア。ただ見てるだけで終わります。元データは完全に消去されるので注意は必要。interactive対話形式でリストア。カスタマイズやNFS上のISOを指定する時に選択します。expertシェルプロンプトを起動する。fdiskとかも実施する場合はこちらで。 [shell] boot: nuke [/shell] 今回は全て自動でレストアします。実際「nuke」を入力する以外に何もする事はありませんでした。 DVDメディア1枚(約4GB)なら30分もあればレストアまで完了しました。 DVDドライブの書き込み速度が24倍速だと、全ての工程が1時間くらいで終わります。 今後の使い方ですが、ISOデータをAWSで保管するとか クラウド上での利用方法(AMI作れるからプライベート上)とか その他の商用ソフトとの比較も実施してみたいです。 AWS Storage Gateway また、「Mondo Rescue」はUNIXに対応していないのでSolarisでufsdumpの他にもっと快適にできる 方法も探したいと思います。 参考サイト Mondo rescueを用いたシステムリカバリの方法 Mondo Rescueのバックアップデータをリストアするには Mondo Rescue...DEVLABをリニューアルしました
2014年 明けましておめでとうございます。 年末年始の休暇を利用してDEVLABのサイトリニューアルを行いました。 何気に3回目のリニューアルなのですが、今回はWordPressのテーマ自体を新しく作り直したので結構大規模リニューアルになりました。正月の後半は半ば家族サービス放棄で連日徹夜気味に作業してました・・・(笑) また、今回のリニューアルタイミングにてWordPressも3.7.1へアップグレードしました。実は年末にバージョン3.8も出ていたのですが、まだ日本語ローカライズ版は提供されていないので、最新安定版の3.7.1までとしてあります。 昨年は多忙にかまけて投稿機会を逸してなかなか投稿数が伸びなかった私maenoですが、今年は心機一転して色々と投稿して行きたいと思いますので、本年もDEVLABともども弊社デベロッパーメンバーをよろしくお願いいたします。...MySQLでALTER TABLEでINDEXを作成するときの注意事項
こんにちは。Ops側の小宮です。 ある日朝来たら突然開発の方から相談いただいたので、後のために記録しておこうと思います。 相談内容: jenkinsで本番デプロイを行ったが、処理を途中停止した。 (CakeのDBマイグレーションスクリプトでデプロイした) KEYカラムにINDEXをはろうとしたがDBの応答がなくなり接続できなくなった。 結果としてテーブルが破損したためRDSの時刻指定してロールバックする機能を用いた。 (ALTERが終わってたかどうかとかはロールバックしたので不明) 同じレコード数の試験環境で同じ操作をしたら特に異常なくすんなり終わった。 もう一回同じことを本番でやりたいけどどうしましょう。 MySQLのバージョンは5.5.27。 私の個人的認識: 普通、ALTERする時はロックがかかるから、 事前に同じ構成と件数の試験環境でかかる時間を見積もってから その時間サービス止めてメンテ入れるべきです。 (※5.5まで。5.6から一部のALTERはオンラインで大丈夫になったようです。) sorry表示に切り替えて更新のない環境でやってみましょう。 (既存のELBの下のwebを全部はずして、別のサブドメインのwebにvhost切ってsorryコンテンツおいてELBに入れるとか) 途中で強制終了とかするとMyISAMだとテーブル壊れやすそう。 show full processlist;で現在のクエリとかかってる時間は見ることができる けどkillするのは最終手段かと。 alter table mysqlとか、それプラス5.6とかでググると色々わかります。 sh2さんのブログを見ると、以下のように書かれています。 MySQLでALTER TABLE文の進捗状況を確認する - SH2の日記 -————— MySQLでは 変更後の定義にもとづく作業用テーブルを作成し、 変更前のテーブルから作業用テーブルへデータをコピーして、 最後に二つのテーブルを入れ替えるという仕組みになっています。 テーブルへのインデックス追加についても、現在のところ大半の ケースで内部的にALTER TABLE文が実行されています。 どこまですすんでるのか確認する方法: SHOW GLOBAL STATUS LIKE ‘Handler_write’; 作業開始前にHandler_writeの値と対象テーブルのレコード件数を控えておけば、 どこまで処理が進んだのかを確認することができるのです。 InnoDBならinnotopをつかうと、row operationsのビューにズバリIns/Secがあるので、 同様にしてALTER TABLEの完了予想が立てられますね。...Mondo Rescue使ってみました(その1)
おはようございます。インフラの宮下です。 最近クラウド環境でイメージ作成ばかりしていたので、たまにはオンプレミス環境で フルバックアップも取得してみます。 目次 はじめに 環境 mondorescueのインストール サーバのフルバックアップ 参考サイト 1.はじめに 定常的にOSバックアップをとるという案件で無く更新作業の前にバックアップを取得する必要があり色々とバックアップツールを検討していました。商用の検証もいくつか実施したのですが、今回はオープンソースの「Mondo Rescue」というバックアップツールを使ってみたいと思います。 オープンソースを使う最大の理由は、コストと納期になりますね。計画的な案件であれば商用のバックアップツールの検討が最初になるかと思います。 「Mondo Rescue」を選択した点としましては、NFSマウント先にファイルが保管できさらにそこからレストアも可能という情報が最大の「それ魅力」です。また、メディアからレストアするのも簡単そう(実際に簡単)なのも良さげでした。 2.環境 ロケーション:物理サーバ(富士通製) OS:Red Hat Enterprise Linux Server release 6.4 3.mondorescueのインストール 最初にmondorescueのリポジトリを追加します。 [shell] vi /etc/yum.repos.d/mondorescue.repo [mondorescue] name=rhel 6 x86_64 - mondorescue Vanilla Packages baseurl=ftp://ftp.mondorescue.org//rhel/6/x86_64 #baseurl=ftp://213.30.161.23//rhel/6/x86_64 enabled=0 gpgcheck=1 gpgkey=ftp://ftp.mondorescue.org//rhel/6/x86_64/mondorescue.pubkey #gpgkey=ftp://213.30.161.23//rhel/6/x86_64/mondorescue.pubkey [/shell] 準備完了と言う事でmondorescueリポジトリを使ってmondo resucue本体をインストールします。 [shell] # yum install mondo –enablerepo=mondorescue =================================================================================================================================== Package Arch Version Repository Size =================================================================================================================================== Installing: mondo x86_64 3....natインスタンスの冗長化
こんにちは。プラットフォームの小宮です。 他を冗長化してもnatインスタンスを冗長化してないと、 プライベートセグメントでHAしてるサーバ達がAWSのAPIサーバと通信できなくなって詰むなあと思いまして、 先人の皆さまの記事を参考にして以下のとおりにしました。 **・なんとなくどうするか検討 ** AmazonLinuxで作っちゃったので、たぶんHeartbeatとか入れづらいし、そもそもheartbaet使う必要ない気がする。 待機系から監視してaws的にルーティングテーブル挿げ替えるだけでよさそう。 待機系natインスタンスについて、 作成しておかないと作成と起動とルーティングテーブル作るところもやらないといけないので切替時間が長くなる。 インスタンス代がかかるけど起動もしたままがいいと思われ。 **・とりあえず既存のAmazonLinuxのNATインスタンスの設定をいじるところから ** sudoできるようにしてみる # usermod -G wheel user-op # id user-op uid=500(user-op) gid=501(user-op) groups=501(user-op),10(wheel) # visudo %wheel ALL=(ALL) ALL コメントはずす。 他のインスタンスから渡ってsudoできるか確認する あとnatインスタンスにpythonのツール入れておく メール送信も設定 AmazonLinuxではsendmailが動いてる模様だった。 vi /etc/mail/submit.cf D{MTAHost}[172.18.10.22] Djnat01.hoge.com ※nat02はそう変える service sendmail stop chkconfig sendmail off yum install mailx echo hoge |mail -s testkomi komiyay@xxxxx ロケールを合わせる...