Red Hat - Open Innovation Labsのブログ - TECH PLAY

TECH PLAY

Red Hat  - Open Innovation Labs

Red Hat - Open Innovation Labs の技術ブログ

全900件

Red Hatの中山です。先日、OpenShift Service Mesh 1.0 が GA になったので、インストールしてみます。 blog.openshift.com OpenShift 4の他のOperatorと同様、ServiceMeshはOperatorHubからインストールするのですが、今回は、すべてコマンドラインからインストールします。ドキュメントには、GUIからインストールする方法が書かれているので、GUIがお好きな方はドキュメントを読みながらGUIからインストールしてみてください。 docs.openshift.com インストールコマンドの実行には、cluster-adminかそれ相当の権限が必要になります。 最初に、ServiceMeshのオペレーターをインストールします。CatalogSourceConfigとSubscriptionを作ります。 cat <<EOF | oc apply -f - apiVersion: operators.coreos.com/v1 kind: CatalogSourceConfig metadata: name: ci-operators namespace: openshift-marketplace spec: targetNamespace: openshift-operators packages: elasticsearch-operator,jaeger-product,kiali-ossm,servicemeshoperator source: redhat-operators --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: elasticsearch-operator namespace: openshift-operators spec: channel: preview name: elasticsearch-operator source: ci-operators sourceNamespace: openshift-operators --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: jaeger-product namespace: openshift-operators spec: channel: stable name: jaeger-product source: ci-operators sourceNamespace: openshift-operators --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: kiali-ossm namespace: openshift-operators spec: channel: stable name: kiali-ossm source: ci-operators sourceNamespace: openshift-operators --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: servicemeshoperator namespace: openshift-operators spec: channel: "1.0" name: servicemeshoperator source: ci-operators sourceNamespace: openshift-operators EOF openshift-operatorsプロジェクトで、以下の4つのPodがRunning状態になればOKです。ElasticSearch、Jaeger、Kialiは不要なんですけど...と言う方も、現時点(1.0GA時)では、Operatorのインストールが必要になります。ただ、Operatorのインストールが必要となるだけで、これら3つが不要な場合には、実際のインスタンスをインストールする必要はありません。実際、今回の手順では、ElasticSearch、Jaeger、Kialiはインストールしません。 $ oc get pod -n openshift-operators NAME READY STATUS RESTARTS AGE elasticsearch-operator-54b656cbb4-9bwdn 1/1 Running 0 11m istio-operator-64f969655b-vwnks 1/1 Running 0 11m jaeger-operator-55f47cccbc-x99rn 1/1 Running 0 11m kiali-operator-865b8cfc7b-kbm69 1/1 Running 0 11m Opeeratorのインストールが終れば、あとは簡単、ServiceMeshControlPlaneを作成して、istioのPodをデプロイするだけです。今回は、最小限で以下の構成にします。 oc new-project istio-system cat <<EOF | oc apply -f - apiVersion: maistra.io/v1 kind: ServiceMeshControlPlane metadata: name: minimal-multitenant-cni-install namespace: istio-system spec: istio: global: multitenant: true proxy: autoInject: disabled omitSidecarInjectorConfigMap: true disablePolicyChecks: false defaultPodDisruptionBudget: enabled: false istio_cni: enabled: true gateways: istio-ingressgateway: autoscaleEnabled: false type: LoadBalancer istio-egressgateway: enabled: false cluster-local-gateway: autoscaleEnabled: false enabled: true labels: app: cluster-local-gateway istio: cluster-local-gateway ports: - name: status-port port: 15020 - name: http2 port: 80 targetPort: 8080 - name: https port: 443 mixer: enabled: false policy: enabled: false telemetry: enabled: false pilot: autoscaleEnabled: false sidecar: false kiali: enabled: false tracing: enabled: false prometheus: enabled: false grafana: enabled: false sidecarInjectorWebhook: enabled: false EOF 上記の構成でデプロイすると、 istio-system プロジェクトに、以下のPodが起動します。 $ oc get pod -n istio-system NAME READY STATUS RESTARTS AGE cluster-local-gateway-76cc6d67c4-z8g86 1/1 Running 0 67m istio-citadel-7cb44f4bb-khr2d 1/1 Running 0 68m istio-galley-75599dbc67-k9z2c 1/1 Running 0 68m istio-ingressgateway-769c96c46f-lp9zf 1/1 Running 0 67m istio-pilot-7c7dd546f9-mfnzq 1/1 Running 0 67m 以上で、インストールが終わりました。OpenShift 4共通に言えることですが、Operatorを利用しているため、インストールはとても簡単です。Istio定番のbookinfoアプリなんかで遊んでみてください。ドキュメントもあります。 docs.openshift.com ちょっとした注意点として、ドキュメントにも書かれていますが、OpenShiftでServiceMeshをインストールする場合、CNIプラグインを有効化しているので、 ServiceMeshMemberRoll というリソースを作ってcontrol planeとsidecarのやり取りを許可する必要があります。例えば、bookinfoプロジェクトを利用する場合は、以下の設定を忘れずに。 cat <<EOF | oc apply -f - apiVersion: maistra.io/v1 kind: ServiceMeshMemberRoll metadata: name: default namespace: istio-system spec: members: - bookinfo EOF 最後に、今回の記事は説明が少ないし、「やってみた(だけ)」記事だし、ServiceMeshインストールして、この後どうすれば良いか分からない、という方!次回の「OpenShift Meetup Tokyo」は、Service Mesh & Serverless 特集です。ぜひ、参加して更なる深い話を聞いたり、参加者で情報を共有しましょう。 openshift.connpass.com
お疲れ様です!Red Hatの鈴木(tomosuzu)です! 今回は「ユーザーストーリーマッピング」です。 実際に作ってみたら思っていたものと違った なんてこと防ぐために関係者全員の共通理解があることが大切です。 詳しくは下記のリンクからご覧ください。 tomosuzu.com 次回は「バリューストリーム・マッピングおよびプロセスマッピング」を紹介します。 さいごに Red Hatでは、「アイデアをイノベーションに変える、文化・プロセス・技術・実践の場」として、 Open Innovation Labs を提供しています。 デザイン思考やDevOps、アジャイルやリーン開発などをRed Hatのコンサルタントと一緒に取り組むことができます。 過去記事 アジャイル開発のプラクティス一覧をご紹介いたします - 赤帽エンジニアブログ チームの知識共有とコミュニケーションを増やします「ペアプログラミング 」 - 赤帽エンジニアブログ 速い開発速度を保ち、着実に開発を進める「テスト駆動開発」 - 赤帽エンジニアブログ チームの自律性・自主性を高める「社会契約」 - 赤帽エンジニアブログ チームの健康状態を知り、様々な問題に事前に対処「チーム感情の評価」 - 赤帽エンジニアブログ 改善のサイクルを小さく回す「ふりかえり」 - 赤帽エンジニアブログ 目標を明確にして、チームを集中させる「スプリント計画」 - 赤帽エンジニアブログ 機能ではなく、ビジネスゴールをデリバリする「インパクトマッピング」 - 赤帽エンジニアブログ チームを同期し、目標の認識強化「毎日のスタンドアップミーティング」 - 赤帽エンジニアブログ ユーザーを身近にし、認識を共有する「共感マッピング」 - 赤帽エンジニアブログ
Red Hat の古市です。 developers.redhat.com に掲載された記事を和訳しました。まだ読まれていない方は、是非ご覧ください。 原文: developers.redhat.com 著者: Christina Lin 和訳: playintegration.blogspot.com 10月9日(水)の夜には、著者 Christina Lin をゲストスピーカーに迎え、無料セミナーをおこなう予定です。 jcug-oss.connpass.com 上記告知サイトに詳細内容が掲載されており、参加登録も可能です。お時間のある方は是非ご参加ください。告知サイトの最後には、" その他 参考資料 "とカテゴライズされたリンク集があります。どれも読み応え充分の記事となります。こちらも是非ご確認ください。
この記事は、以下のシリーズの6つ目の記事です。 Red Hat Summit 事例翻訳:Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft ( 前の記事はこちら ) 最後に、これからの大きな賭けの話をしましょう。 ネットワーク自動化の将来はどうなるでしょう。 私たちのチームが、どこに到達しようとしているのか。 Red Hatと提携していることで、エンタープライズの領域であろうがどこでも取り組むことができるようになりました。 また、我々が志向している、最大のものの1つがネットワークモデリングです。 現在、我々は小規模にはネットワークモデリングを既に採用しており、いくつかのPoCを終えています。 これによって、私たちが本当にやりたいことは、デバイスのコンフィグレーションです。 ですが、私達はデバイスコンフィグレーションとデバイスモデリングからは少し離れようと思っています。 デバイス上の設定には、他のデバイスとリンクするための非常に多くの複雑なデータがあります。そのため、それらをネットワークモデル化しないということは不可能な規模に近づいているという見方をしています。 2つ目については、Single source of truth(信頼できる唯一の情報源)についてです。 かつて、私がネットワークエンジニアから言われた言葉を教えましたが覚えていますか?『デバイスの正しい構成情報が知りたいなら、実際にログインしてチェックしたら?』でした。 多くの人々は、これをintent based networking(意図に基づくネットワーキング)と呼んでいます。デバイスへは、必要なインテントを定義します。 このアイディアに到達するには、メタデータでかつIDを持つようになるのではと思います。 そしてそれらはサービスとして実行するようになるでしょう。 サービスは、Single source of truthになりうるGit、SQL、またはCosmosDBに基づいて、デバイスのコンフィグレーションを定義し、これを使用して、Incident Management Platformなどの多くのアップストリームシステムにリンクすることができるでしょう。 同じように私たちはそれを私たちのチケット管理システムにリンクさせることができます。例えば私たちはそれを私たちのIPアドレス管理データベースにリンクさせることができ、実際にこれらすべての情報を引き出してNW機器の自身に対するクロスチェックを検証することができるようになります。 そして、最後にEvent Based Automationです。 これは本当に大きなものです。 おそらく今後数年の間にやってきて、これにシフトしていくことになるでしょう。 私達は今日早くにRed Hatと会い、彼らがこの分野でAnsibleでしていることについて議論してきています。 彼らもまたこのEvent Based Automationでネットワーク自動化の文脈で”If This Then That”のような自動化をどのように始めるのか?にフォーカスしていています。 高度なテレメトリをトリガーするためのイベントをもつ必要があるという考えがあります。 出て行き、デバイスからより多くのテレメトリを収集し始めたり、さらにアドバンスなテレメトリを利用して送付を有効にしたり無効にしたりする。 実際、ネットワークモデリングについて話すときには、ネットワークモデリングはプッシュとプルの両方で行われるため、コンフィグレーションをデバイスから中央のコレクタにプル、プッシュすることができます。 高度なジオメトリを使ってシステムに常に過剰な電力を供給するのではなく、必要に応じてより高度なテレメトリをそのコレクタに送信できるようにすることができます。 もちろん自動化の文脈も登場します。現在も少しやってますが、システムで何かが起こった際に別のシステムで実際にアクションをトリガーするようなものです。 ハイブリッドクラウドのような考えでは、ネットワーク自動化システムの一部ではない別の自動化システムに対して通知したいような場合もあるでしょう。 Azure Automationかもしれませんし、他のタイプの自動化システムかもしれませんが、実際にそれをトリガーするか、ある時点で別のグループを別のTower環境を呼び出して何かを実行させたりするかもしれません。 最後は分析(Analytics)です。 どんなところでイベントが発生するのか、どのように対処するのか。イベントが発生した時にどのような影響があるオペレーションを決定するのか。 ああ、このイベントはみたことがあるぞ。このイベントが10分後に発生した時にはデバイスがクラッシュするのでいますぐ何かをやっておく必要がある。そんな感じです。 私のプレゼンテーションはこれで全ておしまいです。 少し早いかもしれませんが、最後にこのメモで終わりたいと思います。 これは、昨日の基調講演 www.youtube.com でも多く取り上げられていたものです。 私たちの会社の使命は、この地球上で多くの人たちがより多くの物事を達成できるようになることです。 昨日、ステージ上にいるサティアを私たちは一緒に見ました。 私はこのミッションステートメントを本当に信じています。 今、私はMicrosoftで働くことを本当に誇りに思っています。私たちは素晴らしいことをやっているんだ!と感じているのです。 Linuxカンファレンスで、まさかMicrosoftがステージに立つときがくるとは夢にも思っていませんでした。 でも、今私はここに立っています。 しばらく、ブースにいますので何か質問があればこちらに来てください。Swagと、ペンギンが書かれたクールなMicrosoft Tシャツを持って待ってます。  これで、私のプレゼンを終わります。    今日はどうもありがとうございました。
この記事は、以下のシリーズの5つ目の記事です。 Red Hat Summit 事例翻訳:Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft ( 前の記事はこちら ) そして、最後にAutomation Communityについてお話しましょう。 MS社内の自動化コミュニティについて 私たちはチームの中にコミュニティを作りました。 そしてこのコミュニティは私たちがすべての質問をリダイレクトするところでもあります。 ある時、気が付いたのですが、たくさんの人たちが私たちのオフィスにやって来て質問をしているということです。そしてそれらの質問の多くは素晴らしい質問でした。 私たちは、これらの質問をどのようにまとめるか?ということを考えました。 書き留めてから、後でこれらの質問を投稿する場所を作り、eメールで送信しました。 結果、我々がやり始めたことで、開発チームの多くの負荷を軽減しました。 自動化のコミュニティがあるのなら、参加するべきでしょう。 我々は、誰もこのコミュニティへ強制的な参加やメンバー追加をしていません。参加することは完全にオプションです。ですが、もし同じようなコミュニティがあるなら、参加することをおすすめしますし、そこで質問をするべきです。 我々がオートメーションコミュニティを開始するや否や、爆発的に広がりました。 誰もが質問をし始めました。そしてその大部分は私たち専属チームのメンバーが答えているのではなく、組織内の他のエンジニアが質問に対して回答をしていました。 エンジニアの特性について、一つお教えしましょう。 エンジニアに問題を与えた時に、彼らは質問に対して回答をする最初の人間になりたいという、誇りのような感覚を持っています。 なので、コミュニティになにがしかエンジニアへの質問を投稿した場合、それをきっかけに大量の人がGoogleでその答えを検索に行くか(冗談)、回答してくれようとします。 それは20人のエンジニアが何かを実装するための正しい方法について議論するために反応しているようなもので、どんどんと会話に拍車をかけていきます。 会場にいるみなさんがMicrosoft Teamsを使っているかどうかはわかりませんが、Teamsを使っている我々のようなケースでいうと、すべて異なるTeamsにメンバーとして追加されているはずです。 自動化コミュニティは?私たちの組織にある、私たちが持っている、1つのTeamsであり、そこへアクセスしたい全ての人が参加できる場所で、本当にうまくいっています。 誰もが参加してくれました。 コミュニティの質は、まさしく素晴らしいものです。 さて、この文化的な変革は何が正しく見えるようになったのでしょうか? 冒頭で申し上げたように、我々の自動化はネットワークでシンプルなスクリプトを扱うところから始まりました。 interface,何とかかんとか、shutdown, no shutdown...それらのコマンドが羅列されるPlaybookを書き始めました。 そして、ロジックを埋め込んだPlaybook。 デバイスのタイプを決定するPlaybook。 端末上のメタデータを読み込むPlaybook。 変更を加える前に特定の設定を検索することではるかにスマートになったPlaybookでは、APがダウンしたときにAPの復旧指示まで自動化するような本当にクールなことを実行でき、スクリプト内で決定を下すことができます。 我々は、『ネットワークエンジニア』が『ネットワーク デベロッパー』に変わったところを見てきました。 そして今はネットワークエンジニアが、ネットワークデベロッパーに変わったことを本当に実感しています。 もはやCLIを用いて日常を浪費することはないので、なにがしかの問題を解決するためには今ではそれ以外の方法を用いることを考えています。 ネットワークデベロッパーは私たちのプラットフォーム上でソリューションを開発しました。 彼らは、彼らのネットワークスペースに問題があることを知っているので、そこにたくさんのブラウンフィールド(再利用されない)なコードを持っていました。 それらはスノーフレーク(密結合)な状態で、自動化することは容易ではありませんでした。 どのようにプロセスを構築することできたのか、我々はまだまだCLIコマンドを利用しています。 CLIコマンドを利用し、相互にレビュープロセスを必要としています。 標準的な変更なので実行できますが、一度そのプロセスが完了すると、その後はAnsibleがそれらのコマンドを実行し、そのおかげで実際に承認したユーザーや何が実行されたのかを確認して追跡できます。 これは、私たちが過去にしていたことよりも、もっと目が行き届いた、より良いプロセスになりました。 そしてスライドの下の方に書かれているのは、我々が使っているツールたちです。 GitHubエンタープライズを利用している100人以上のエンジニアがいます。 Gitはすべてのグループや組織で使用されています。 Ansibleは、至る所すべてのユーザーで、最も重要な流行語(Buzzword)です。 また、さまざまなチームがPythonの様々な利用方法を検討しています。 Pythonを使用して双方向的で、かつ迅速で新しいデータ変換をネットワークデバイスへ行えるようにする方法などを検討しようとしています。 MicrosoftはCosmoDB(Azureの大規模なデータベースサービス)を持っているので、様々なFact(Ansibleで収集できるデータセット)を収集しています。エンジニアがデータベースから様々なFact情報を読みにいけることで、より良いネットワーク構築を行うために彼らが何をすべきかなどの判断をその場で決定できるようにしようとしているのです。 そして、我々もたくさんのアジャイルサービスを利用するようになってきましたが、誰もがクラウドを利用しています。 最後に、これからの大きな賭けの話をしましょう。 ( 次回 へ続く)
この記事は、以下のシリーズの4つ目の記事です。 Red Hat Summit 事例翻訳:Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft ( 前の記事はこちら ) さて、スキルセットの育成について話しましょう。 組織内で早い段階で構築しているスキルセットについて少し話しました。 Microsoftには、本当に数多くのCLI大好きエンジニアがいっぱいいます。 すぐにCLIにログインしたがるし、彼らが何か欲しいなぁと感じる何かの為に本当にたくさんのコマンドをタイプします。 しかし、数十、数百、数千と管理対象のネットワーク端末が増えていき、さらに高度なことにトライをしようと思った時。もはやPythonのような言語を必要としていました。 決定的だったのは2年前の出来事です。 ネットワーク機器の情報を集める必要があった時、誰かが『じゃあ全部のデバイスにログインするか』と言い出したんです。全ての端末にログインをして、インターフェースの統計情報を読んで、何が悪いのかを伝えると。これがターニングポイントでした。 これが、10の端末であれば? 問題無いでしょう。 これが100の端末だったならば? 多分無理だし、さらに17,000のデバイスを与えて同じことをやれと言われたら? 考えなくてもわかります。絶対に無理です。 では現在は? どうやってやるのか。考えを転換しました。 Pythonか何かを使ってどうやるのか?という方向です。 netmikoのようなライブラリを用いて全ての端末にログインできるようになれば、情報を簡単に取得することができます。取得した情報を用いてその場で決定を下すようなこともできます。 先述の状態を変えるため我々はPythonからスタートしましたが、数年前にAnsibleを知るに至りました。 Ansibleを用いた変革の旅は、とても面白いものでした。 それはエンジニアたちに問題と言うていで、何かクイズを与えているのと同じだからです。 ほとんどのものはProblemフォーム上で起票されます。 エンジニアたちは起票された問題を自ら引き受け、自分が対処するつもりだというでしょう。彼らはPlaybookを作るつもりです。 そして、本当に私が欲しかった、150ものPlayが連なる長いPlaybookがどんどんと出来上がるのです。 Pull Requestが出来上がり、75から150のなにがしかの実行能力をみんなに提供してくれるのです。 ほとんどの場合、完璧なRolesを作り上げてくれます。 慣れてくると、AnsibleではRolesが作れ、それがエンジニアそれぞれの責任範囲になってくるとわかってきます。 我々はほとんどの仕事をplaybookにしてしまいましたが、もっと仕事を楽にしていくためにAnsible自体のUpstreamコミュニティへの技術提供も開始しました。 そしてこれこそが、私たち全員に新しいスキルセットの構築を開始するよう皆を説得し得るものでした。 私自身、実際には2年前、組織内でGitトレーニングを受けていませんでした。 3年前、我々の技術分野ではチームにもGitのエキスパートはいませんでした。 しかし前述の通りで組織をさらに引き上げるつもりがあるなら、Gitに熟練しなければと考えました。 どんな質問にも答えることができる専門家が必要だと思ったのです。 なので、私は恐竜の着ぐるみでトレーニングを受けました。 実際に私は恐竜の着ぐるみを着て仕事をすることができるようになったのは世界で最もすばらしい出来事でしたが、最初のブランチを紙で切り出してテープで貼った時は本当に最高でした。 しかし、これが本当に文化を大きく変えていったのです。 今日、エンジニアは一人で仕事をしている訳ではありません。400人のエンジニアがチーム全員で新たに参加してきます。 それらの新しいエンジニアは、Gitを知らない人たちです。 そういった人たちを、我々の社内コミュニティでは、皆が意欲を共有したいという気持ちを持っていて、そんな人たちがビデオトレーニングを受けて、ドキュメントを読んで、質疑をしあい、そして皆Gitを知るに至っています。    これは、船の行く先を変えたいがための最初の出発時点での話でした。 これは、Zero to Heroと呼ばれる教育プログラムです。 最初はHero To Zeroと勘違いしていました。 どう自動化を育んでいくのか、というのはずっとポイントで、我々はずっと議論を重ねてきました。 エンジニアの一人がこのプログラムを考えついて、我々の中でこのプログラムを作り上げてきました。 Ansibleをどんどん浸透させて色々な人を自動化に参加させたかったので、トレーニングプログラムには色々な人に参加してもらいました。 トレーニングにおいてはAnsibleのPlaybookの書き方、Roles、再利用性、本番環境への適用承認からの実行フローなど自動化のコンセプトとして必要なこと全てを学び、全ての内容について答えることができるくらいの能力を身につけさせます。 なぜか。Playbookの書き方をよく知って欲しいからです。 何故なら、下手なPull Requestを出した後は50-100件程度のコメントがつくこともあるのですから。 コメントが多すぎたり、ツールに慣れていなかったりして、それらの対処方法もわからず、150もの批判的なコメントがついたりしたらせっかく頑張ってPlaybookを作ってPR出したのに、『ああ失敗したな』とメンバーは感じることでしょう。そんなことは見たく無いんです。 ではどうやってそれを回避するのか?正直簡単ではなかったです。 我々はこのトレーニングを実施して、私たちはZero to Heroを開始したのです。 組織全体をどんどんと前進させ、自動化に適合させるためです。 さらに、我々はセッションを行いました。 Zero to Heroの最初の2ヶ月は環境の設定を実施し、どれほど環境が複雑なのかを知り、自分のPCのVisual Studio Codeのことを知り、Gitのことを知り、レポジトリを取得したりPullしたり、GitHub Enterpriseへのログイン方法、GitHub Enterpriseとはなんなのか、最初の数ヶ月でプルリクを実施するためには何をしたら良いのか?などなど。 本当に色々なことを新しく学んでいきました。 そして、結果として非常に快適になっています。 我々は本当に変わったのです。 今はこのプログラムは少し変えています。 実際のエンジニアのレベルに合わせて構成しています。 100, 200, 300, 400というクラスベースで割り当てています。 100のクラスはシンプルな環境設定のセットアップのクラスです。 環境設定、Gitのインストール方法、リポジトリのクローン作成方法、2要素認証とGitHubエンタープライズの設定方法など、とても簡単なものです 。 レベル200のクラスになると、どうやって最初のプレイブックを書くのかについて話し始めます。Rolesとは何か、そしてそれらをどうやって見つけることができるか。これらのRolesをどう扱い、再利用することができるのか。なぜなら、自動化をさっさと利用可能な状態にしたいのと、早く結果を残すことが大事だからです。 そして300, 400のクラスです。 非常に高度なトピック用にこれらを準備しています。テストの書き方など、オートメーションプラットフォーム内に独自のテストスキームを持っています。 400のコースを実施する時には、真剣に受講者と会話をします。 今度、Pull Requestを実施するとどんな複雑なことが起こっているのかを見せます。 そこで何が起きるのを見るのか? 現在、だいたい5〜6人のエンジニアが我々の組織内にいるのですが、彼らはネットワークエンジニアとかネットワーク開発者と呼べるような存在です。 彼らはpull requestされたコードをチェックする準備ができています。彼らが王国への鍵を管理しているので本当に安心できるようになっています。 あなた(受講者)が書いたコードは高品質で優れていることが、周りの皆が書いたコードからも証明されているので、プロダクションに安心してプッシュすることができるんですよ!と言うことを、彼らに認識させることができるのです。 そして、最後にAutomation Communityについてお話しましょう。 ( 次回 へ続く)
この記事は、以下のシリーズの3つ目の記事です。 Red Hat Summit 事例翻訳:Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft ( 前の記事はこちら ) Microsoftは文化を作り上げました。 そこでは自動化の新機能をリリースするために協力したとして皆が名前をクレジットしたいと考えるようになったので、新たなCoolな取り組みにどんどんと参加するようになっています。 そして、これを実現するためにMicrosoftはAnsible Towerを購入しインストールすることにしました。そして、自動化のプラットフォームを構築し、そのトップにAnsible Towerを置いたのです。 加えて、いくつかのAPIのインテグレーション層を加えました。 また、このストレージ/データ層を加えています。 この辺りの詳細は後ほどお話しましょう。 ほとんどのネットワーク機器の設定は、稼働しているデバイスにのみ保存されています。 ネットワークエンジニアに現状のコンフィグレーションの状況を尋ねると、彼らは『実機を見に行けば?』と言ってくるでしょう。 少し話題を変えて、ここからはこのような文化をどのように変革したのか?について話しましょう。 文化の変革をどのように観測するのか? ここでは、まず我々はどのように新しいスキルセットを育てていったのか。 『Zero to Hero』と呼ばれるプログラムについて。 そして最後に自動化コミュニティについてお話しましょう。 文化の変革の成熟度合いを計測する これまでも、たくさんのエンジニア、そのマネージャーたちと一緒に仕事をしてきました。 彼らがネットワーク自動化のコードを書きたいと思っているときに大抵聞くであろう質問があります。 おそらく皆さんも同じだと思います。 5つのステップからなるプロセスで、ネットワーク全体へ自動化を広げようと考えています。 例えば、なにやら自動化と呼ばれるものを今日から君がやるんだと、あなたは上司から聞かされたとします。 そんな時、皆さんは塩かケチャップボトルを扱うみたいに、とりあえず何かの上に自動化というエッセンスを好きなように振りかけられると良いなぁと思いますよね? 昨日のRed Hat SummitのKeynoteでも語られたように、組織の文化を変えるということは本当に重要です。 それは、自分たちの仕事のやり方について、それまでと違った考えをさせること、そしてこれまでやってきた方法をほとんど変えていくということを意味しています。 毎回毎回、どの組織と話しをしても、最初に私が聞かれることは『このStep1から5、そして6へはAnsibleで自動化さえしておけば到達できるのでしょうか。』です。 そしてそれに対する私の答えは Noです。 確かに、Step1~5までは自動化で解決されるべき問題です。 そして、問題に対する取り組み方をこれまでとは変えていくべきです。 なぜならば、自動化を用いて何かしらの問題に取り組んでいった際に、もっともメリットとなるものは非常に標準化されたデプロイメントにあるからです。 皆さんもご存知の通り、とてもたくさんのものがプラットフォームに依存・付属しています。 では、私たちは内部的にどのように計測をしているのか? このセッションが録画されているかどうかはわかりませんが、実はこのスライドをまだ私のリーダーへ見せていません。 私はこのStep5にどのようにたどり着くかということについて、リーダーは問題ないということを確信しているからです。 つまりこのスライドが特に、我々の文化的な変革を内部的にも計測できるスライドとも言えるのです。 では、今度は外側からみてみましょう。 一部の人たちは、『ああ、Microsoftの皆さんはレベル1なんですね。 我々は現在レベル3かそれ以上なのですが、なぜあなたが我々に自動化を語るのですか?』というでしょう。 それは間違った感想だと言えるでしょう。 この図で描かれている箇所(MSはレベル1に到達しているという絵)は、我々が到達している最高地点を表したかった訳ではありません。 実際にはもっと高いレベルに、我々の文化的変革は到達していると考えています。 しかし、組織的にこれらの取り組みを行なった場合、実際には最低水準に合わせた推進の仕方が必要になるのです。 現在では、MSのほとんどの組織が、元々のただスクリプトを記述して手動実行することを自動化と呼んでいたレベルから、現在ではGitを用いてコードのチェックインを行い、リアクティブな自動化の文化を構築する状態へ変換し始めたことを非常に誇りに思っています。 その一つの例として、MSでAP nowと呼ばれるものを作りました。 APやワイヤレスの管理をしたことがあるひと、いますか? 我々がどれくらいの無線APを管理していると思いますか?おそらく、35-40,000程度のBGPがあると思います。 いくつかのBGPはたまに消失します。 大体の場合、ログインして、リブートすれば、APは復帰してくるのでそのあとは様子を見ながら毎日リブートするようになったら交換するという運用をします。 もしくは、おそらく自動的に修正することはできないだろうという理由には、実に20%程度でAPを切り替える必要があるケースがありました。 単に再起動するだけではなく、アラートが発報された場合にいくつかの自動オペレーションを行うよう自動化しました。 問題のワイヤレスコントローラまでログインして、APを復旧しようとさせます。これは全てネットワークエンジニアの手順に基づいています。ここにログが表示されたなら、APの電源がオフになっているかどうか、様々なコマンドで確認をします。もしコマンドが返ってこないなら、機器をリプレースするためのチケットを作成します。 つまり、一連の全プロセスを自動化しました。この作業は、最もチケット数量が多い作業のうちの一つでした。 これができてこそ、Microsoftではレベル1と見ています。 我々は、自動化することで、どのように物事を取り除けるかということを考え始めています。 もはや、誰もAP故障時に出かけて実際に触るというようなことはやる必要がありません。毎回やっているような作業で時間を費やす必要は無いのです。全く同じことです。 レベル2やレベル3へ移行する為に私のチームの何人かが取り組んでいることの一部は、レベル2を達成する為に、自動化をベースとして組織を変換していくという作業です。 私たちは、世界中の人々が、どのようにネットワークが構築され、どのように世界中の人々が繋がっているのかを、みんなに考えてもらいたいのです。Microsoftの為に、最初から最後までやること全てが自動化されている状態について。 それは最初に話していたような部分的に自動化を塩やケチャップみたいにふりかけるというものではなくて、最初かもしくは最後だけログインをしているようなものからは仕事ぶりを変えていく必要があるんです。 そしてレベル3、4、5へ進んでいきましょう。 レベル5、そこは機械学習のような、ソフトウェアセットのより高度なものを実行し始めるときです。 まだ我々もよくその世界のことを知っているわけでは無いですけど、すごく遠いことにように見えますが、全てのことを検出して自動実行するために正しいアクションを学んでいるような高度なアルゴリズムを使用できるところまで到達したいと思っています。 さて、次はスキルセットの育成について話しましょう。 ( 次回 へ続く)
この記事は、以下のシリーズの2つ目の記事です。 Red Hat Summit 事例翻訳:Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft ( 前の記事はこちら ) では、これらの対策に何をしたかをお話しましょう。 行動原則を規定 我々は、エンジニアリングの行動原則を設定・適用しました。 これらは全く誰にとって目新しいものではありませんが、先ほど紹介した問題と相関関係にあります。 我々は、テスト環境を追加しました。 また、そこではバージョンコントロールと本番環境への適用に対する承認行為を採用しました。 Ansibleの環境について 環境について話しましょう。 2年半前に、我々はAnsibleTowerを導入しました。 そして、我々は開発/テスト、プリプロダクション、プロダクションの3つの環境を用意しました。 これら3つの環境にはそれぞれ特定の目的がありそれらの目的の達成が強制されています。 開発/テスト環境においては、過去の環境と同じものが構成されています。 環境へのフルな権限は与えていません。 テストラボの中の端末にしかアクセス・実行できず、それらは仮想環境でネットワークを再現しています。 もしも、ネットワーク全体を再現してテストしたいというリクエストでも、他の人たちを待たせることなくテスト実行するための環境を渡すことができます。 開発/テスト環境で素晴らしいところは、開発者とネットワークエンジニアはお互いに全てのコードにアクセスできることで、どちらのスキル保有者も『ネットワーク開発者(Network Developper)』へのコンバートへトライできることです。 プラットフォームへもログインできますし、テストでラボ全体を使ってテストをして環境を壊すようなコードを書くことができますし、誰かがそれを修正することもできますし、やろうと思えばどんな事にもトライできます。 プリプロダクション環境をみてみましょう。 私たちは完全なネットワークアクセスを持っていますが、開発とマスターのブランチアクセスのみに限定されています。 そして、作成したコードは開発(develop)ブランチに入るためにどのようにプロダクションへの移行を進めるかについて会話を始めたなら、完全なコードレビューを経る必要があり、レビューを経た時点でコードはプロダクション用途として完全なものと考えられます。 そして、プロダクション環境のクラスタです。 最高規模のクラスタで、最も多くのCPU数やメモリを持ち、ここですべてのプロダクションワークロードを実行し、高可用性を確実にするため監視もされているクラスタです。 そして、これらに対する更新作業の裏側ではほとんどがAnsibleTowerを用いて行われています。 Ansible Towerが可能にすることの一つに、バージョンコントロールがあります。 以前は、必ずCLIを用いてそれぞれの環境でコマンド実行の必要性がありました。 そして、他の誰かが知らないうちにログインし、コマンドのたった一つに私が知らない変更を加えて、結果私が実行した時に予期せぬ結果を生み出すようなことが多々ありました。 現在我々はGitHub Enterpriseを用いています。 MicrosoftがGitHubエンタープライズのヘビーユーザーだったのでGitHubを買ったという話がジョークだったと言いたいのですが、冗談ではなかったのでしょう。 実際に我々はGitHubエンタープライズを使い始めました。 私たちはコードをすべてのサーバーに配布し、そしてそれらがきちんと特定のブランチから配布されているかを検証し確認します。 これらを原則とし、ブランチルールなどの規則を適用することができるようになりました。 最終的には、プロダクション環境へのワークフローを承認します。 コードは開発ブランチから分岐したFeatureブランチから始まって、エンジニアたちは本当に様々な面白いコードを多数作成して、それらの開発中コードを繰り返しデバイスに対して実行して、本当に動くかを確実にテストしています。 問題なく動作できた場合には、開発ブランチへのプルリクを実行します。 実際にコードがレビューされ、プロダクションレディかどうかを確認します。 こんな形なので、おそらく誰でも機能開発のコード開発にトライすることができると思っています。 現在では素晴らしいことに、2週に一度、変更があった全てのコードをマスターに適用するような変更を加えることができるようになりました。 すでに組織にいる誰もが自動化に対して取り組めるようになっているし、自動化のコードを書いた全ての人を褒め称えるような組織的なコミュニケーションもやっています。 そして、これが本当に組織文化の変革における始まりだったのです。 例えば、古いシステムで私が自動化のコードを何か新しいものを書いたとして、話したこともないような人がそのコードを信用してくれて、プロダクション環境で実行しようとしてくれるようなことがあると思いますか?それがどう動作するかもわからないのに? 今、Microsoftは文化を作り上げました。 そこでは自動化の新機能をリリースするために協力したとして皆が名前をクレジットしたいと考えるようになったので、新たなCoolな取り組みにどんどんと参加するようになっています。 そして、これを実現するためにMicrosoftはAnsible Towerを購入しインストールすることにしました。そして、自動化のプラットフォームを構築し、そのトップにAnsible Towerを置いたのです。 ( 次回 へ続く)
この記事は、以下のシリーズの1つ目の記事です。 Red Hat Summit 事例翻訳:Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft ( 前の記事はこちら ) MicrosoftのソフトウェアエンジニアリングチームのマネージャのBart Dworakです。 今日は、Microsoftが文化をどのように変えたのか? そしてその変化のためにRed Hatと協力しAnsible Towerをどのように使用しているのかをこのセッションではお話ししようと思います。 では、これまでのMicrosoftとは?を話しましょう。 我々は、Microsoftの内部ネットワークを管理するチームです。 400+のインフラエンジニアがおり、全世界で600+のオフィスなどの管理をしています。 例えば、WirelessやVPNの整備をし、Microsoftの全ての従業員へ使わせるような業務というとわかりやすいと思います。 2015年では13,000ほどの設備を管理していましたが、2019年には17,000台以上の設備管理が必要になっていました。 現在では、ネットワーク設備の管理だけではなくAzure上で利用しているさまざまな資産の管理も開始しています。 それまで、自動化は手がけていなかったのでしょうか? いいえ。手がけていましたが、Ansible Towerを導入するよりも前は単純なスクリプトが中心でした。 そういったスクリプトによる自動化のようなものでも、単純にコマンド実行はできていました。 ですが、レスポンスを見ながら何かをするような作業を自動化することは難しかったです。 そんなかつてのMicrosoftのネットワークエンジニアのスキルセットは、CLIが中心で、みんなPutty(日本でいうTeraterm)が大好きで、どんな変更をするにもログインをする必要がありました。 このやり方は、10-20か30-50程度のネットワークを管理するにはとても合っています。 ですが、今日話をするのは17,000以上を管理するための話です。 同じやり方を続けての管理は不可能です。 こちらが、本日お話をしたいアジェンダです。 agenda まず、我々がこれまでエンジニアリングにおいてどのような問題・課題と対峙していたかをお話ししたいと思っています。 次に、我々が打ち立てたエンジニアとしての行動原則や、今どのあたりまで達成したのかを。 文化を変革するために何をやってきたのか。 実際に変革の過程のなかでどのような問題と対峙したのか。 打ち立てたエンジニアの行動原則(Engineering Principles)がどのようにMicrosoftの組織としての文化を変えたのか。 それらはどう我々の将来の価値になるのか?ネットワークの何を自動化しているのか?などです。 エンジニアリングにおける問題点とは では、まずエンジニアリングの何に問題があったのか? 結論から入ると、バージョン管理がされていない状態で、本番環境の設定を実行していました。 何が正しいのかの確証は環境内部にしかありませんでした。 エンジニアリング組織として、2つの環境を我々は持っていました。 過去に保有していた2つの環境 プリプロダクション環境とプロダクション環境です。 どちらのネットワークにも完全なアクセス権限があり、それを良しとしてきました。 あなたが、スクリプトを書いてどんな驚くような変更だろうと実行できてしまうプリプロダクション環境を持っています。 一方で、プロダクション環境での操作はとてもハードですよね。 エンジニアとしては、全ての作業をプリプロダクション環境で実行しようと選択するようになるでしょう。 皆さんも同じような経験をされましたか? プリプロダクションの環境では承認などもいらないので簡単になんでもできて、プロダクション環境では絶対に何もできなくなるんです。 これまでのツールでは、バージョン管理に対応できていませんでした。 ツールにログインして、全ての実行する必要があるスクリプトをマニュアル実行する必要がありました。 このやり方を、色々な設備で同じように実行する必要があったんです。 同じようなスクリプトをなんども手動で実行させるというのは、エンジニア達に色々なところで様々な問題を引き起こさせるにはとてもいいやり方です。 スクリプトがプリプロダクション環境ではゴロゴロと転がっていて、その辺でイノベーション(皮肉)が生まれています。 それらのスクリプトをあなたが書いている訳ではなかった場合、途端に本番環境で実行するには信頼するに足りないコードの塊を所持していることと同義になってしまいます。 なので、すでに言ったように、これらはプリプロダクションからプロダクション環境へコードや設定を移す際に発生する、もっとも大きな問題の一つになります。 どこにも何も問題がないということを調査するために、メールをし、たくさんのエンジニアたちと話して確認する必要があり、精査をしていく必要があるのです。 これには膨大な時間がかかります。 もし、自分の仕事を終わらせたいということが第一目標になった場合、同じような確認作業を確実にやろうと思うでしょうか? 良いコードというのは、プリプロダクション環境で一度でも問題なく実行できれば良いコードと見られます。 そしてこれらの両方の環境への完全なネットワークアクセスを持っています。 私やエンジニアに取って、もっとも抵抗が少ないやり方は、プリプロダクション環境で問題無ければ良しとすることです。 結果として何が起きるのかは想像にお任せします。 では、これらの対策に何をしたかをお話しましょう。 ( 次回 へ続く)
レッドハットのソリューションアーキテクト、金森です。   数回に渡り、今年5月にボストンで開かれた Red Hat Summit 2019 で事例講演がされたMicrosoft社のAnsibleTowerの事例セッションについて翻訳したものをポストします。   Red Hat SummitにおけるRHEL8発表の様子 はじめに このブログポストは本セッションのスピーカーで、Microsoft社のSoftware Engineering ManagerであるBart Dworak氏の快諾を得てポストするに至りました。 本セッションで語られる、Bart氏の惜しみのない改善への努力とその過程や結果の共有、そしてAnsibleコミュニティへのコントリビューションに対し、深い感謝の意を一人のAnsibleユーザとしてここに表します。 本セッションでは、Microsoft社の社内ネットワークの管理について、自動化という考え方を取り入れながら、その考え方をどう定着させていくのか?そして定着をさせるためには何が必要だったのか?それらの中で何を学んだのか?が多く語られました。 DXという言葉がbuzzword化して久しいですが、Microsoft社におかれてもこのBuzzwordに単純には乗ることのできない昔ながらのネットワーク機器の管理の考え方(根付いてしまった文化)を変えることは容易ではなかったとのことです。 Bart氏の経験は、きっと日本のAnsibleユーザやCommunityへも良いInsightsを与えると思いこの翻訳を手がけました。 また、MicrosoftとRed Hatが協力しあいMicrosoftの文化を変えた、という何年か前にはあり得なかった内容がRed Hat Summitというオープンソースのお祭りで語られることも非常に趣深いものがありました。 最後に、来月アトランタで開催される Ansible Fest ではこのセッションの内容をUpdateし、 Bart氏が再度登壇 するとのことです! 参加される方はぜひUpdateを聞きに行くととてもアツいセッションを聞けるかもしれません・・・! 特にNetworkに携わるエンジニアで自動化に悩んでいる方は必聴です。 [登壇直前のBart氏] さて、前置きが長くなりました。 はじめに セッションサマリー セッション名 登壇者について Abstract その他セッション情報について セッション資料、Red Hat Summitについて セッションサマリー セッション名 Analog transformation: Scaling network automation culture with Ansible Tower at Microsoft (翻訳)アナログからの転換: マイクロソフトにおいて、ネットワーク自動化の文化をAnsible Towerを用いて拡大させた話 登壇者について Speaker: Bart Dworak, Software Engineering Manager, Microsoft Bart氏は、Microsoftのソフトウェアエンジニアリングマネージャで、Microsoftにおいてクリティカルな内部ネットワークの運営方法を変革するためのチームを率いています。 彼のチームはMicrosoftのエンジニアがより生産的に、そしてより多くの成果を達成することを可能にするツールとプラットフォームの提供にフォーカスしています。 彼の重点分野は、ネットワークチームの文化的変革、次世代ネットワーク自動化技術に向けての考え方の転換、および大規模環境での自動化です。 Abstract 進化する世界においてネットワークを自動化するということは重要な要素ですが、これはツールだけにとどまる話ではありません。 セッションでは、MicrosoftがRed Hat Asnisible Towerを用いて、いかにネットワーク自動化を推進し、これまでの設計、構築、デプロイのやり方、文化を今日および将来に向け変革をしたかを紹介します。 その他セッション情報について 場所: Red Hat Summit@Boston アメリカ 開催日時: 5/8 4:30 p.m.-5:15 p.m. セッション資料、Red Hat Summitについて 資料や上記のアブストは Red Hat Summit 2019のサイト からダウンロード・確認することができます。 では、 次のポスト からセッションの内容に入っていきましょう。
Red HatでOpenShiftのテクニカルサポートエンジニアをしている Daein(デイン) です。 Operator を Operator SDK で作成して OpenShift で稼働させてみます。ドキュメントのサンプルOperatorの作成のみでは情報が足りないと思っている方に、Operator作成手順をコードコメントを入れてstep by stepで解説していきます。 docs.openshift.com 既にOperatorという用語に慣れている方が多いかもしれませんが、簡単に紹介します。Operatorとは管理業務を自動化する目的でKubernetes Controllerを実装するパターンで、Operator SDKはそのOperatorを簡単に作成できるようにしてくれる開発ツールです。 docs.openshift.com docs.openshift.com ドキュメントに記載されている手順とは別のサンプル実装として、メンテナンスページの切り替えを行うOperatorを作成してみます。このOperatorは、アプリケーションpodとメンテナンスページ用podの2つのpodをデプロイし、それら2つのpodのアクセスを切り換えます。詳細なフローとCR( CustomResource )の定義は次のようになっています。 maintpage-operator-process-diagram apiVersion : maintpage.example.com/v1alpha1 kind : MaintPage metadata : name : example // メンテナンスページ用のPod名はCR名をベースに生成されます。例> example-maintpage-pod spec : maintpageconfig : maintpagetoggle : false // trueにするとServiceはメンテナンスページ用のPodに振り分けするように変更されます。 maintpageimage : quay.io/daein/maintpage:latest // メンテナンスページ用のコンテナイメージ appconfig : appname : httpd // アプリケーション用のPodをデプロイするDeploymentと関連Serviceはこの名前で作成されます。 appimage : quay.io/daein/prodpage:latest // アプリケーション用のコンテナイメージ 上記のCR( CustomResource )を作成するとOperatorが次のタスクを実施してくれるように作成します。 メンテナンスページのみ表示するPod(example-maintpage-pod)を作成する アプリケーションページを表示するPod(httpd)をスケジュールするDeployment(httpd)と紐づいたService(httpd)を作成する maintpageconfig.maintpagetoggle を利用してアプリケーションページ又はメンテナンスページへの振り分けを操作する 現状どのページを表示しているか確認できる Maintpublishstatus 項目を提供する Deploymentで参照するイメージのマニュアル変更を許可しない Operator SDKの設置 この記事ではLinuxをベースに進めておりますが、MacOSも利用可能です。詳細は次のリンク先を参照してください。 docs.openshift.com Goのインストール $ GOVERSION=1.12.9 $ wget https://dl.google.com/go/go${GOVERSION}.linux-amd64.tar.gz $ tar -zxvf go${GOVERSION}.linux-amd64.tar.gz $ mkdir -p $HOME/projects/src $ vim ~/.bash_profile export GOPATH=$HOME/projects export GOROOT=$HOME/go export PATH=$GOROOT/bin:$PATH export GO111MODULE=on $ source ~/.bash_profile Operator SDKのインストール $ sudo yum install mercurial -y $ mkdir $HOME/bin $ RELEASE_VERSION=v0.10.0 $ curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu $ mv operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu $HOME/bin/operator-sdk $ chmod u+x $HOME/bin/operator-sdk 動作確認 $ go version go version go1.12.9 linux/amd64 $ operator-sdk version operator-sdk version: v0.10.0, commit: ff80b17737a6a0aade663e4827e8af3ab5a21170 以上で、インストール完了です。早速プロジェクトを作成してOperatorを作成してみましょう。 Operatorの作成 下記で紹介するコードはロジックの実装のみ記載していてエラー及びログ処理は省略しています。 作業用のプロジェクトを作成: ディレクトリパスは環境に合わせて調整してください。 $ mkdir -p $GOPATH/src/github.com/bysnupy $ cd $GOPATH/src/github.com/bysnupy $ operator-sdk new maintpage-operator --repo github.com/bysnupy/maintpage-operator $ cd maintpage-operator CRD( Custom Resource Definition )用のAPIを追加 $ cd $GOPATH/src/github.com/bysnupy/maintpage-operator $ operator-sdk add api --api-version maintpage.example.com/v1alpha1 --kind MaintPage CRで設定できる設定項目を定義: 修正した内容のみ記載しています。 $ vim $GOPATH/src/github.com/bysnupy/maintpage-operator/pkg/apis/maintpage/v1alpha1/maintpage_types.go // CRの操作時に利用する項目パラメータを定義 type MaintPageSpec struct { MaintPageConfig MaintPageConfig `json:"maintpageconfig"` AppConfig AppConfig `json:"appconfig"` } // CRのStatusセクションの項目パラメータを定義 type MaintPageStatus struct { MaintPublishStatus string `json:"maintpublishstatus"` } ...省略... // 次は項目をまとめて定義するために追加したデータタイプで必要に応じて追加したりしてください。 type MaintPageList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` Items []MaintPage `json:"items"` } type MaintPageConfig struct { MaintPageToggle bool `json:"maintpagetoggle"` MaintPageImage string `json:"maintpageimage"` } type AppConfig struct { AppName string `json:"appname"` AppImage string `json:"appimage"` } maintpage_types.go の内容が変更された後には忘れずに operator-sdk generate k8s で 修正内容に合わせて必要なコードを再生成してください。 $ cd $GOPATH/src/github.com/bysnupy/maintpage-operator $ operator-sdk generate k8s 上記の手順で追加したCR(MaintPage)の定義に合わせてどのように操作するか実装するコントローラーを追加してください。 $ cd $GOPATH/src/github.com/bysnupy/maintpage-operator $ operator-sdk add controller --api-version maintpage.example.com/v1alpha1 --kind MaintPage 基本的に次の順で関数をカスタムしてロジックを実装します。 CRUDのイベントを監視(Watch)するリソースを指定します。 指定したリソースにイベントが発生するたびにカスタムロジックが適用・一致(Reconcile)されます。 $ vim $GOPATH/src/github.com/bysnupy/maintpage-operator/pkg/controller/maintpage/maintpage_controller.go // イベントを監視したいリソースを次の関数配下で追加してください。 func add(mgr manager.Manager, r reconcile.Reconciler) error { ...省略... // メンテナンスページ用のPodがあるかチェックして作成するため、Podも追加します。 err = c.Watch(&source.Kind{Type: &corev1.Pod{}}, &handler.EnqueueRequestForOwner{ IsController: true , OwnerType: &maintpagev1alpha1.MaintPage{}, }) // デフォルトでMaintPageは監視されますので、マニュアルでイメージが変更されることを検知するためDeploymentを次の通り追加します。 err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ IsController: true , OwnerType: &maintpagev1alpha1.MaintPage{}, }) ...省略... // MaintPageとDeploymentでCRUDのイベントが発生した時、どのような処理をするか次の関数で実装してください。 func (r *ReconcileMaintPage) Reconcile(request reconcile.Request) (reconcile.Result, error ) { // メンテナンス用のPodがない場合、新しく作成します。 pod := newPodForMaintPage(maintpage) podfound := &corev1.Pod{} err = r.client.Get(context.TODO(), types.NamespacedName{Name: maintpage.Name + "-maintpage-pod" , Namespace: pod.Namespace}, podfound) if err != nil && errors.IsNotFound(err) { reqLogger.Info( "Creating a new Pod" , "Pod.Namespace" , pod.Namespace, "Pod.Name" , pod.Name) err = r.client.Create(context.TODO(), pod)      } // CRで定義したAppNameのDeploymentが存在しない場合、新しく作成します。 depfound := &appsv1.Deployment{} err = r.client.Get(context.TODO(), types.NamespacedName{Name: maintpage.Spec.AppConfig.AppName, Namespace: maintpage.Namespace}, depfound) if err != nil && errors.IsNotFound(err) { dep := r.deploymentForApp(maintpage) err = r.client.Create(context.TODO(), dep)      } // CRで定義したAppNameのServiceが存在しない場合、新しく作成します。(今回ServiceはWatchに追加していないため、監視されません。) svcfound := &corev1.Service{} err = r.client.Get(context.TODO(), types.NamespacedName{Name: maintpage.Spec.AppConfig.AppName, Namespace: maintpage.Namespace}, svcfound) if err != nil && errors.IsNotFound(err) { // Define a new service svc := r.serviceForApp(maintpage) err = r.client.Create(context.TODO(), svc) } // CRで定義したMaintPageToggleがtrueの場合、Serviceをメンテナンスページ用のPodをEndpointとして変更してStatusセクションのMaintpublishstatusをPublishedにセットします。 if maintpage.Spec.MaintPageConfig.MaintPageToggle { svcfound.Spec.Selector[ "app" ] = maintpage.Name err := r.client.Update(context.TODO(), svcfound) statusErr := r.client.Status().Update(context.TODO(), updateMaintStatus(maintpage, "Published" )) } else { if svcfound.Spec.Selector[ "app" ] != maintpage.Spec.AppConfig.AppName { svcfound.Spec.Selector[ "app" ] = maintpage.Spec.AppConfig.AppName err := r.client.Update(context.TODO(), svcfound) } // Update Status statusErr := r.client.Status().Update(context.TODO(), updateMaintStatus(maintpage, "Not Published" )) }       // Deploymentの参照イメージがCRと一致しないと元に戻します。 if depfound.Spec.Template.Spec.Containers[ 0 ].Image != maintpage.Spec.AppConfig.AppImage { depfound.Spec.Template.Spec.Containers[ 0 ].Image = maintpage.Spec.AppConfig.AppImage err := r.client.Update(context.TODO(), depfound) } コードとしては長いですが、内容はシンプルです。Watchで登録したリソースに対してイベント発生時の状態をチェックし、想定している状態に一致させるロジックを実装するだけです。実際にDeploymentやServiceを作成するなどのCRUD操作を実装したClient APIのより詳細な情報は次のリンクを参照してください。 https://github.com/operator-framework/operator-sdk/blob/master/doc/user/client.md github.com 残りの関数は各リソースの定義をKubernetes APIで実装したものになります。どのように定義しているかみてみましょう。 // メンテナンスページ用のPodをCRで定義した名前とイメージをベースに作成する関数になります。 func newPodForMaintPage(m *maintpagev1alpha1.MaintPage) *corev1.Pod { maintpageimage := m.Spec.MaintPageConfig.MaintPageImage labels := map [ string ] string { "app" : m.Name, } return &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: m.Name + "-maintpage-pod" , Namespace: m.Namespace, Labels: labels, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: "maintpage" , Image: maintpageimage, }, }, }, } } // アプリケーション用のPodをCRで定義した名前とイメージをベースにデプロイする関数になります。 func (r *ReconcileMaintPage) deploymentForApp(m *maintpagev1alpha1.MaintPage) *appsv1.Deployment { appname := m.Spec.AppConfig.AppName appimage := m.Spec.AppConfig.AppImage replicas := int32 ( 1 ) dep := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: appname, Namespace: m.Namespace, }, Spec: appsv1.DeploymentSpec{ Replicas: &replicas, Selector: &metav1.LabelSelector{ MatchLabels: map [ string ] string { "app" : appname}, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map [ string ] string { "app" : appname}, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{{ Image: appimage, Name: appname, }}, }, }, }, } // Set MaintPage instance as the owner and controller controllerutil.SetControllerReference(m, dep, r.scheme) return dep } // CRで定義した名前でServiceを作成する関数になります。 func (r *ReconcileMaintPage) serviceForApp(m *maintpagev1alpha1.MaintPage) *corev1.Service { appname := m.Spec.AppConfig.AppName svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: appname, Namespace: m.Namespace, }, Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{{ Name: "8080-tcp" , Protocol: "TCP" , Port: 8080 , TargetPort: intstr.FromInt( 8080 ), }}, Selector: map [ string ] string { "app" : appname}, }, } // Set MaintPage instance as the owner and controller controllerutil.SetControllerReference(m, svc, r.scheme) return svc } // StatusセクションのMaintPublishStatus項目を渡された引数に合わせてセットする関数です。 func updateMaintStatus(m *maintpagev1alpha1.MaintPage, status string ) *maintpagev1alpha1.MaintPage { m.Status.MaintPublishStatus = status return m } コードの全文は このGitHub から確認できます。 Operatorのビルド及び設置 次の手順でOperatorをビルドしてイメージを適切なレジストリにpushしてください。また、メンテナンスページ及びアプリケーションページのコンテナイメージは別途用意してください。こちらではhttpdコンテナにそれぞれ"Maintenance Page !"と"Production Page !"が記載されたindex.htmlを追加したものでテストしています。 Operatorのビルド $ oc create -f $GOPATH/src/github.com/bysnupy/maintpage-operator/deploy/maintpage_v1alpha1_maintpage_crd.yaml $ cd $GOPATH/src/github.com/bysnupy/maintpage-operator $ go mod vendor $ operator-sdk build quay.io/daein/maintpage-operator:v0.0.1 $ sed -i 's|REPLACE_IMAGE|quay.io/daein/maintpage-operator:v0.0.1|g' deploy/operator.yaml $ sudo docker push quay.io/daein/maintpage-operator:v0.0.1 Operatorの設置: プロジェクト名は適切にご調整ください。設置前にpushしたレジストリからイメージpullできるか確認してください。 $ oc new-project maintpage-operator $ oc create -f deploy/service_account.yaml $ oc create -f deploy/role.yaml $ oc create -f deploy/role_binding.yaml $ oc create -f deploy/operator.yaml $ oc get pod -n maintpage-operator NAME READY STATUS RESTARTS AGE maintpage-operator-6df9d9c85c-s7xmw 1/1 Running 0 20s CR(MaintPage)を定義してメンテナンス及びアプリケーションページ用のPodを作成してください。 $ oc create -n maintpage-operator -f - <<EOF apiVersion: maintpage.example.com/v1alpha1 kind: MaintPage metadata: name: example spec: maintpageconfig: maintpagetoggle: false maintpageimage: quay.io/daein/maintpage:latest appconfig: appname: httpd appimage: quay.io/daein/prodpage:latest EOF $ oc get pod -n maintpage-operator NAME READY STATUS RESTARTS AGE example-maintpage-pod 1/1 Running 0 20s httpd-784b46459b-spfzg 1/1 Running 0 19s maintpage-operator-6df9d9c85c-s7xmw 1/1 Running 0 40s $ oc get svc httpd -n maintpage-operator NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd ClusterIP 172.30.131.106 <none> 8080/TCP 21m Operatorの動作チェック CRの Maintpagetoggle を true に更新してメンテナンスページの切り替えとDeploymentのイメージをマニュアルで更新しても変更されないか確認しましょう。 次の通り、Deploymentのイメージはマニュアルで変更しても更新されないことが確認できます。 $ oc edit deployment/httpd -n maintpage-operator ... spec: containers: - image: quay.io/daein/prodpage:notfound $ oc get deployment/httpd -o yaml | grep image: - image: quay.io/daein/prodpage:latest 次の通り、CR(MaintPage)の Maintpagetoggle を true / false に更新することでページ表示が変わることが確認できます。 // 変更前の状態は"Maintpublishstatus: Not Published"です。 $ oc describe maintpage example -n maintpage-operator Name: example ... Status: Maintpublishstatus: Not Published Events: <none> // 別のターミナルでService当てにリクエストし続けてページの変更をモニターしましょう。 $ while :; do echo "$(date '+%H:%M:%S'): $(curl -s http://httpd.maintpage-operator.svc.cluster.local:8080)" ;sleep 1; done 23:55:17: Production Page ! 23:55:18: Production Page ! 23:55:19: Production Page ! ... // "maintpageconfig.maintpagetoggle: true"に更新してください。 $ oc edit maintpage example -n maintpage-operator ... spec: ... maintpageconfig: ... maintpagetoggle: true // 表示ページが"Production Page !"から"Maintenance Page !"に変更されることが確認できます。 $ while :; do echo "$(date '+%H:%M:%S'): $(curl -s http://httpd.maintpage-operator.svc.cluster.local:8080)" ;sleep 1; done ... 23:55:57: Production Page ! 23:55:58: Production Page ! 23:55:59: Maintenance Page ! 23:56:01: Maintenance Page ! 23:56:02: Maintenance Page ! // 更新した後の状態は"Maintpublishstatus:  Published"になりました。 $ oc describe maintpage example Name: example ... Status: Maintpublishstatus: Published Events: <none> maintpagetoggle: false に戻して元の状態になるかも確認してください。 本記事では任意で決めた仕様に合わせてOperator SDKを利用してどのようにOperatorが作成されるかみてみました。こちらで紹介している内容以外でも実装仕様によっては finalizer やOLM( Operator Lifecycle Manager )の実装も検討する必要があるでしょう。既に数多くのOperatorが OperatorHub.io とGitHubで提供されて Open Source として公開されていますので実装に困った時には参考にすると良いと思います。 operatorhub.io github.com
お疲れ様です!Red Hatの鈴木(tomosuzu)です! 今回は「共感マッピング」です。 ユーザーを意識した開発は、PM、デザイナー、開発者など どの役割の人にとっても大事なことです。 下記のリンクからご覧ください。 tomosuzu.com 次回は「ユーザーストーリーマッピング」を紹介します。 さいごに Red Hatでは、「アイデアをイノベーションに変える、文化・プロセス・技術・実践の場」として、 Open Innovation Labs を提供しています。 デザイン思考やDevOps、アジャイルやリーン開発などをRed Hatのコンサルタントと一緒に取り組むことができます。 過去記事 アジャイル開発のプラクティス一覧をご紹介いたします - 赤帽エンジニアブログ チームの知識共有とコミュニケーションを増やします「ペアプログラミング 」 - 赤帽エンジニアブログ 速い開発速度を保ち、着実に開発を進める「テスト駆動開発」 - 赤帽エンジニアブログ チームの自律性・自主性を高める「社会契約」 - 赤帽エンジニアブログ チームの健康状態を知り、様々な問題に事前に対処「チーム感情の評価」 - 赤帽エンジニアブログ 改善のサイクルを小さく回す「ふりかえり」 - 赤帽エンジニアブログ 目標を明確にして、チームを集中させる「スプリント計画」 - 赤帽エンジニアブログ 機能ではなく、ビジネスゴールをデリバリする「インパクトマッピング」 - 赤帽エンジニアブログ チームを同期し、目標の認識強化「毎日のスタンドアップミーティング」 - 赤帽エンジニアブログ
Red Hat ソリューションアーキテクトの小島です。 今回はタイトル通り、仮想化の入れ子機能であるNested KVMの使い方を紹介します。以下は忙しい人向けのまとめです。 Nested KVMはRHEL7.3+, RHEL8.0+で利用可能 (ただし、全てのケースでTech Preview扱い) Linux Kernel 3.12でリリースされたIntel CPU対応のNested KVM機能が、RHEL7にもバックポート Red Hat OpenStackでもHeat Templateを利用して、コンピュートノードのRHELにNested KVMを設定可能 2020年6月追記 RHEL8.2からNested KVMの利用を一部サポートするようになりました。サポート条件は下記のとおりです。 Intel x86_64 CPUの利用 (Xeon v3+) L0のOS(ホストOS)とL1のOS(仮想マシン上のOS)は、RHEL8.2+ L2(仮想マシン上の仮想マシン)のOSでサポート対象となるものは、RHEL6+, Windows 10+, Windows Server 2016+ AMD CPUでのNested KVMは、現時点ではサポート対象外となります。サポート条件の詳細は下記をご参照ください。 RHEL8.4以降で、再びTech Preview扱いになりました。 access.redhat.com 最近だと開発や製品検証にコンテナを利用することも増えてきていると思いますが、仮想化機能を使っているケースもまだまだ多いと思います。ISVの製品も仮想化用のアプライアンスとして提供していることがありますので、そのような場合に仮想化の入れ子機能が使えると、仮想化環境上でもさくっと検証できるようになります。OpenStackのような複数のマシン台数が必要になるIaaS製品の検証でも便利です。 CentOSやFedoraでのNested KVMの設定方法を紹介しているブログは多いですが、実はRHELでも使えます。Linux kernel 3.12のリリースに伴い、 Intel CPUに対応したNested KVM機能を本格的に使えるようになりましたが、 この機能はLinux Kernel 3.10系をベースとしたRHEL7のカーネルにもバックポートされています。Nested KVMは全てのケースでTech Preview機能となり、Red Hatのサポート対象外の機能となります。また、RHEL7.3+、RHEL8.0+でないと使えませんので注意してください。Nested KVMはデフォルトで無効化されていますので、下記のようなコマンドを実行して設定を行ってください。 # cat << EOF > /etc/modprobe.d/kvm.conf options kvm_intel nested=1 <- AMD系のCPUの場合は、「optionns kvm_amd nested=1」を指定 EOF # modprobe -rv kvm_intel <- AMD系のCPUの場合は、「kvm_amd」 を指定 # modprobe -v kvm_intel <- AMD系のCPUの場合は、「kvm_amd」 を指定 RHEL8の場合は、仮想化機能に関するパッケージをインストールすると、Nested KVMを利用するための設定がコメントアウトされた「/etc/modprobe.d/kvm.conf」が予め用意されているので、コメントアウトを解除してkvm_intelまたはkvm_amdモジュールをリロードします。これでNested KVMが有効になりますので、virshやvirt-installなどでNested KVMを設定・利用できるようになります。この場合は、仮想化ホストのCPU機能をゲストが利用するような設定を行います。 新規に仮想マシンを作成 # virt-install ... --cpu host ... <- ホストのCPUを利用するオプションを指定 既存の仮想マシンを編集 # virsh edit <vm_domain_name> ... <cpu mode='host-model' check='partial'> <- cpu_mode='host-model'を指定 <model fallback='allow'/> </cpu> ... GUIで設定する場合、執筆時点ではRHEL7とRHEL8のWebコンソールであるCockpitでは仮想マシンのCPU設定を行えないので、virt-manager(RHEL8では非推奨扱い)などで設定する必要があります。virt-managerを利用する場合、[CPU数] の [ホストCPUの設定をコピーする] にチェックを入れて、変更を保存します。 また、RHELをベースとしたRed Hat OpenStack(バージョン15からRHEL8対応予定)でもNested KVMを利用するように設定できます。この場合は、Nested KVMの設定をデプロイするためのHeat TemplateファイルをYAMLで作成して、 openstack overcloud deploy コマンドでovercloudをデプロイする手順を実行します。手順の例は下記のナレッジベースを参考にしてください。 access.redhat.com なお、Nested KVMを利用した場合、どのくらいパフォーマンスが落ちるのかを弊社エンジニアがテストしています。これによると、製品の機能検証をする場合は、L2ゲスト(仮想マシン上の仮想マシン)くらいまでに留めておいた方が良さそうです。 www.redhat.com
お疲れ様です!Red Hatの鈴木(tomosuzu)です! 今回は「毎日のスタンドアップミーティング」です。 朝会として、やっている組織も多いかと思います。 下記のリンクからご覧ください。 tomosuzu.com 次回は「共感マッピング」を紹介します。 さいごに Red Hatでは、「アイデアをイノベーションに変える、文化・プロセス・技術・実践の場」として、 Open Innovation Labs を提供しています。 デザイン思考やDevOps、アジャイルやリーン開発などをRed Hatのコンサルタントと一緒に取り組むことができます。 過去記事 アジャイル開発のプラクティス一覧をご紹介いたします - 赤帽エンジニアブログ チームの知識共有とコミュニケーションを増やします「ペアプログラミング 」 - 赤帽エンジニアブログ 速い開発速度を保ち、着実に開発を進める「テスト駆動開発」 - 赤帽エンジニアブログ チームの自律性・自主性を高める「社会契約」 - 赤帽エンジニアブログ チームの健康状態を知り、様々な問題に事前に対処「チーム感情の評価」 - 赤帽エンジニアブログ 改善のサイクルを小さく回す「ふりかえり」 - 赤帽エンジニアブログ 目標を明確にして、チームを集中させる「スプリント計画」 - 赤帽エンジニアブログ 機能ではなく、ビジネスゴールをデリバリする「インパクトマッピング」 - 赤帽エンジニアブログ
こんにちは、Red HatのChristian Hornです。 Red Hat Enterprise Linux (RHEL)には、様々なソフトが入っています。その上、EPEL8もリリースされました。 EPELのパッケージはレッドハットのサポート対象に入っていません。 詳細: Extra Packages for Enterprise Linux (EPEL) の使用方法 - Red Hat Customer Portal EPEL8をインストールしましょう: [root@rhel8a ~]# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm Updating Subscription Management repositories. メタデータの期限切れの最終確認: 0:00:37 時間前の 2019年08月16日 09時58分51秒 に実施しました。 epel-release-latest-8.noarch.rpm 3.5 kB/s | 21 kB 00:06 依存関係が解決しました。 ============================================================= パッケージ アーキテクチャー バージョン リポジトリ サイズ ============================================================= Installing: epel-release noarch 8-5.el8 @commandline 21 k トランザクションの概要 ============================================================= インストール 1 パッケージ 合計サイズ: 21 k インストール済みのサイズ: 30 k これでよろしいですか? [y/N]: y パッケージのダウンロード中です: トランザクションの確認を実行中 トランザクションの確認に成功しました。 トランザクションのテストを実行中 トランザクションのテストに成功しました。 トランザクションを実行中 準備 : 1/1 Installing : epel-release-8-5.el8.noarch 1/1 scriptletの実行中: epel-release-8-5.el8.noarch 1/1 検証 : epel-release-8-5.el8.noarch 1/1 Installed products updated. インストール済み: epel-release-8-5.el8.noarch 完了しました! [root@rhel8a ~]# その時に、一つなリポジトリだけ使えるようになっています: [root@rhel8a ~]# egrep '^\[|enabled' /etc/yum.repos.d/epel* /etc/yum.repos.d/epel-playground.repo:[epel-playground] /etc/yum.repos.d/epel-playground.repo:enabled=0 /etc/yum.repos.d/epel-playground.repo:[epel-playground-debuginfo] /etc/yum.repos.d/epel-playground.repo:enabled=0 /etc/yum.repos.d/epel-playground.repo:[epel-playground-source] /etc/yum.repos.d/epel-playground.repo:enabled=0 /etc/yum.repos.d/epel-testing.repo:[epel-testing] /etc/yum.repos.d/epel-testing.repo:enabled=0 /etc/yum.repos.d/epel-testing.repo:[epel-testing-debuginfo] /etc/yum.repos.d/epel-testing.repo:enabled=0 /etc/yum.repos.d/epel-testing.repo:[epel-testing-source] /etc/yum.repos.d/epel-testing.repo:enabled=0 /etc/yum.repos.d/epel.repo:[epel] <--- これが使えます /etc/yum.repos.d/epel.repo:enabled=1 <--- /etc/yum.repos.d/epel.repo:[epel-debuginfo] /etc/yum.repos.d/epel.repo:enabled=0 /etc/yum.repos.d/epel.repo:[epel-source] /etc/yum.repos.d/epel.repo:enabled=0 [root@rhel8a ~]# これから普通に使えます: [root@rhel8a ~]# dnf -y install screen iftop openvpn Updating Subscription Management repositories. [..] 完了しました! [root@rhel8a ~]# [root@rhel8a ~]# rpm -q screen iftop openvpn screen-4.6.2-10.el8.x86_64 iftop-1.0-0.21.pre4.el8.x86_64 openvpn-2.4.7-1.el8.x86_64 [root@rhel8a ~]#
Red Hatの平です。今回も知っている人は使っている Red Hat UBI のお話です。前回の記事を読んでいない方は、こちらから rheb.hatenablog.com Podman でのコンテナーイメージのビルド方法 カスタムのコンテナーイメージをビルドする方法として、現在のところメジャーどころなのが Dockerfile です。 Podman では podman build コマンドにて Dockerfile を読み込んでカスタムのコンテナーイメージをビルドすることができます。 今回はCentOS 7上にてコンテナーエンジン Podman を使い、Red Hat UBI のコンテナーイメージをビルドする方法についてご紹介します。 Dockerfile のサンプルの取得 今回は弊社のエンジニア Fernando Lozano がGitHubに公開しているサンプルがありますので、こちらを使って試してみましょう。 github.com # git clone https://github.com/flozanorht/testphp-ubi.git Dockerfile の中身を確認してみましょう。こちらはApache上のPHP 7.2で動くHello Worldのサンプルです。 # cd testphp-ubi # cat Dockerfile.ubi8 FROM registry.redhat.io/ubi8/ubi #FROM registry.access.redhat.com/ubi8/ubi RUN yum --disableplugin=subscription-manager -y module enable php:7.2 \ && yum --disableplugin=subscription-manager -y install httpd php \ && yum --disableplugin=subscription-manager clean all ADD index.php /var/www/html RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \ && mkdir /run/php-fpm \ && chgrp -R 0 /var/log/httpd /var/run/httpd /run/php-fpm \ && chmod -R g=u /var/log/httpd /var/run/httpd /run/php-fpm EXPOSE 8080 USER 1001 CMD php-fpm & httpd -D FOREGROUND Dockerfile のビルド では podman build コマンドでコンテナーをビルドします。Dockerfile.ubi8 を指定しないとRHEL 7ベースのUBIが使われますのでご注意ください。 # podman build -t php-ubi -f Dockerfile.ubi8 . STEP 1: FROM registry.redhat.io/ubi8/ubi Getting image source signatures Copying blob c585fd5093c6 skipped: already exists Copying blob e61d8721e62e skipped: already exists Copying config c7a62535df done Writing manifest to image destination Storing signatures STEP 2: RUN yum --disableplugin=subscription-manager -y module enable php:7.2 && yum --disableplugin=subscription-manager -y install httpd php && yum --disableplugin=subscription-manager clean all Red Hat Universal Base Image 8 (RPMs) - AppStre 828 kB/s | 1.9 MB 00:02 Red Hat Universal Base Image 8 (RPMs) - BaseOS 812 kB/s | 737 kB 00:00 Dependencies resolved. ================================================================================ Package Arch Version Repository Size ================================================================================ Enabling module streams: httpd 2.4 nginx 1.14 php 7.2 ((...snip)) Complete! 16 files removed 94987b2a05737c44f7aeb04b46351f86441472f07c7dec43f6c1f92c1dabfc2d STEP 3: ADD index.php /var/www/html 6785efbf7402f112bcd8f97cbf16272fffc30be6a149e0c3fbec27c911ad3f9f STEP 4: RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf && mkdir /run/php-fpm && chgrp -R 0 /var/log/httpd /var/run/httpd /run/php-fpm && chmod -R g=u /var/log/httpd /var/run/httpd /run/php-fpm 86200cf38336a1f4f150020c070c77a7235d110bf03e286b724628cd618ef805 STEP 5: EXPOSE 8080 e3b0aea4dbd16430da84676d7eeb79030e0386c11553228a68b8907e9e258cb0 STEP 6: USER 1001 fc1bd8a3049a8b014fc3afdbcd7bf955773966e4ef30516010ec5446e0201cc4 STEP 7: CMD php-fpm & httpd -D FOREGROUND STEP 8: COMMIT php-ubi 783fd57d5c4064a8099a3067c2f8b0106e1b329f0470961f9e5947197645aa33 コンテナーイメージの動作確認 ビルドがうまくできたら完成したコンテナーイメージを動かしてみましょう。curlコマンドでリクエストが戻ってきたら成功です。 あとは、コンテナーを止めて消しておきましょう。 # podman run --name hello -p 8080:8080 -d localhost/php-ubi 0eb31fc1e5cdfcabf4db2e07c13014d4b0391d5fdfe6eaf1c20896015f839eaf # curl http://localhost:8080 <html> <body> Hello, world! </body> </html> # podman stop hello # podman rm hello 日頃から CentOS に慣れている方なら、Red Hat UBI は難しくないかと思います。たくさんの人に安全に使って欲しいコンテナーイメージで配りたいと思ったらRed Hat UBI も候補に入れてください。 Red Hat UBI について他にも情報が欲しい場合、Red Hat Developer Blogの次のエントリーの最後に各種リンクがまとまっています。 developers.redhat.com
お疲れ様です!Red Hatの鈴木(tomosuzu)です! 今回は「インパクトマッピング」です。 インパクトマッピングはとてもシンプルですが、強力なグラフィカル戦略的計画手法です。 私も経験してきましたが、多くのプロダクト開発ではビジネスゴールではなく、 機能開発に焦点を当てがちです。 大元にあるビジネスゴールを常に意識することで 不要な機能開発を避けることができ、 最短でビジネスを成功させることができるかもしれません。 下記のリンクからご覧ください。 tomosuzu.com 次回は「毎日のスタンドアップミーティング」を紹介します。 さいごに Red Hatでは、「アイデアをイノベーションに変える、文化・プロセス・技術・実践の場」として、 Open Innovation Labs を提供しています。 デザイン思考やDevOps、アジャイルやリーン開発などをRed Hatのコンサルタントと一緒に取り組むことができます。 過去記事 アジャイル開発のプラクティス一覧をご紹介いたします - 赤帽エンジニアブログ チームの知識共有とコミュニケーションを増やします「ペアプログラミング 」 - 赤帽エンジニアブログ 速い開発速度を保ち、着実に開発を進める「テスト駆動開発」 - 赤帽エンジニアブログ チームの自律性・自主性を高める「社会契約」 - 赤帽エンジニアブログ チームの健康状態を知り、様々な問題に事前に対処「チーム感情の評価」 - 赤帽エンジニアブログ 改善のサイクルを小さく回す「ふりかえり」 - 赤帽エンジニアブログ 目標を明確にして、チームを集中させる「スプリント計画」 - 赤帽エンジニアブログ
Red Hatの平です。アプリケーションの展開形式としてコンテナーイメージが注目を浴びています。今お使いの開発環境は何ですか?CentOS か Ubuntu という方も多いでしょう。 その方はぜひ、Red Hat UBI (Red Hat Universal Base Image)を使ってみてください。Red Hatの品質管理を経て提供されるコンテナーイメージが無償で自由に利用、再配布できます。 Red Hat UBI (Red Hat Universal Base Image) とは Red Hat UBI は Red Hat Enterprise Linuxのサブセットで、OSSプロジェクトやISV(独立ソフトウェアベンダー)がコンテナーイメージを配布するために利用することを意図して作成されています。 一番の魅力としては Red Hat UBI をベースとして作ったコンテナーイメージを RHEL および Red Hat OpenShift 上のコンテナーとして動かす場合には Red Hat からのサポートを受けることができます。それ以外の Docker や Kubernetes などのコンテナー環境で動かした場合でもサポートこそ提供されませんが無償で使っても構わないという太っ腹の提供形態です。 RHELの一部のパッケージはRed Hat UBIでは削られており、RHELのすべてのパッケージが含まれている訳ではありません。具体的にはGUIやCUIのユーザーランドの一部、データベースサーバーなどのパッケージは含まれておりません。 もちろん、Webアプリを動かすために必要な httpd や nginx などのコンテナー上でアプリを動かすためのランタイムとなるパッケージは含まれています。 RHEL 8のローンチのタイミングで誕生しましたが、Red Hat UBI は、RHEL 8ベースのものだけではなくRHEL 7ベースのUBIもご用意してあります。 詳しく知りたい方は、こちらのブログもご覧ください。 www.redhat.com 今回はCentOS 7上にてコンテナーエンジン Podman を使い、Red Hat UBI のコンテナーイメージに如何にアクセスするのか、どのようにRed Hat UBIを使えるのかご紹介します。 Registry Service Accounts の取得 まず、最初に Red Hat UBI のコンテナーイメージを取得する場合にはRed Hat ID もしくは Registry Service Accounts が必要です。 Red Hat IDはカスタマーポータルにログインする時に使うアカウントです。Service Accountは"|"区切りで7桁の数字と任意のアルファベットから構成されます。パスワードとして約700文字のTokenが割り当てられます。 Podman のインストール コンテナーエンジンのpodmanをインストールします。dockerコマンドに慣れている方は podman-docker パッケージもインストールしましょう。 podman-docker を導入すると docker コマンドが podman のエイリアスとなり、それっぽく動きます。 今回の記事ではDockerは邪魔なのでアンインストールします。 ※podman-docker パッケージを入れると docker パッケージと conflict します。podman-docker を入れなければ消さずに同居できます。きちんと使っている人は docker パッケージ消さないでね。 # yum remove docker -y # yum install podman podman-docker -y インストール後に Podman から registry.redhat.io のレジストリにログインします。今回の記事で使うアカウントは Service Account です。 ※共用環境用のコンテナーインフラからログインする場合、管理者のRed Hat IDの代わりに Registry Service Accounts を使用することが望ましいです。 # podman login registry.redhat.io -u '12345678|myaccount' Password: Login Succeeded! UBI の検索 ログインに成功したらRHEL 8ベースのUBIのコンテナーイメージを検索してみましょう。RHEL 7ベースのUBIもありますよ。 一般利用イメージのubi8, 最小化イメージのubi8-minimal, 複数のサービスを起動するために systemd 初期化システムが含まれている ubi8-init があります。 また、目的に応じた OpenJDK / Python / Ruby などがあらかじめ含まれているUBIも用意されています。 # podman search registry.redhat.io/ubi8 --limit 3 INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED redhat.io registry.redhat.io/ubi8 The Universal Base Image is designed and eng... 0 redhat.io registry.redhat.io/openjdk/openjdk-11-rhel8 OpenJDK S2I image for Java Applications on U... 0 redhat.io registry.redhat.io/openjdk/openjdk-8-rhel8 OpenJDK 1.8 Image for Java Applications base... 0 UBI の取得 今回はレジストリからUBI 8のコンテナーイメージを取得します。 イメージのサイズを確認すると約200MBですね。ちなみに極小化した ubi8-minimal は100MB以下です。 # podman pull registry.redhat.io/ubi8 Trying to pull registry.redhat.io/ubi8...Getting image source signatures Copying blob c585fd5093c6 done Copying blob e61d8721e62e done Copying config c7a62535df done Writing manifest to image destination Storing signatures c7a62535df3cebd7cb714574c04fb3aa71b92551c11a164cef461855360d3970 # podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/ubi8 latest c7a62535df3c 3 weeks ago 216 MB UBI イメージを起動してみる 試しにUBIイメージのコンテナーをインタラクティブモードで起動してみましょう。 /etc/redhat-release の中身を見ると「Red Hat Enterprise Linux release 8.0 (Ootpa)」と出てきます。 パッケージレポジトリは通常のRHEL 8のレポジトリではなく、UBIのレポジトリ ubi-8-baseos と ubi-8-appstream が参照されます。 もちろん、UBIのレポジトリからパッケージのアップデートも可能です。 最後に exit してください。 # podman run -it registry.redhat.io/ubi8 bash bash-4.4# cat /etc/redhat-release Red Hat Enterprise Linux release 8.0 (Ootpa) bash-4.4# df -h Filesystem Size Used Avail Use% Mounted on overlay 24G 266M 24G 2% / tmpfs 64M 0 64M 0% /dev tmpfs 2.0G 8.8M 2.0G 1% /etc/hosts shm 63M 0 63M 0% /dev/shm tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup tmpfs 2.0G 0 2.0G 0% /proc/acpi tmpfs 2.0G 0 2.0G 0% /proc/scsi tmpfs 2.0G 0 2.0G 0% /sys/firmware tmpfs 2.0G 0 2.0G 0% /sys/fs/selinux bash-4.4# yum repolist Updating Subscription Management repositories. Unable to read consumer identity This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. Last metadata expiration check: 0:14:34 ago on Wed Aug 14 03:42:28 2019. repo id repo name status ubi-8-appstream Red Hat Universal Base Image 8 (RPMs) - AppStream 769 ubi-8-baseos Red Hat Universal Base Image 8 (RPMs) - BaseOS 645 bash-4.4# exit ここまで Podman から Red Hat UBI を触ってみるところまでご紹介しました。少々記事が長くなりましたので分割します。次回は Podman に Dockerfile を与えてコンテナーイメージを作っていきます。
こんにちは、レッドハットでストレージを中心にクラウドインフラを生業にしている宇都宮です。 いやーG1 Climaxも終わりましたね。今年のG1は矢野が盛り上げてくれたおかげで…ってプロレスの話じゃなくて。Rookですよ。3話目ですね、1クール13話やるまでは打ち切りにならないようがんばります。 前回 は、実際にRookを使ってKubernetes(k8s)クラスター上にCephストレージをデプロイして使ってみました。 今回はCephに障害が起きたとき、Persistent Volume(PV)を使っているアプリケーションのI/Oにどのような影響が起きるかを見てみましょう。 ところで前回OpenShift Meetupというイベントがあることを紹介したのですが、来る9/11(水)に開催予定の OpenShift Meetup Tokyo #6 はストレージ特集です!東京会場の一般席はありがたいことに満席ですが、ブログ/Tweet発信枠と大阪・福岡のサテライト会場にはまだ空きがありますよー! ちなみにOpenShift Meetupは#4から crash.academy さんに録画をお願いしていて、 リプレイ を観ることができるんです!#5の動画はまだですが#4はもう公開されてます。#4で宇都宮がRookとCephについて話してた動画もあるのでユーザー登録して観てみてね! あと勝手に Rookの日本コミュニティ を立ち上げました。コンテンツはまだ何もないけど、ぼちぼちイベントをする段取りができたらここで告知しまーす。 以上番宣でした! worker nodeの追加 はいそれでは本題に入ります。前回はworker nodeが3台でこいつらをapp用とCeph用で兼用してたのですが、今回はCephのノード障害を起こすためにapp用のworkerを分けておきたいと思います。worker nodeを追加して適当にlabelを振って、こんな感じでいきます。(色んな事情からkubernetes再デプロイしてます) [utubo@tutsunom ~]$ kubectl get node -L nodetype --sort-by='{.metadata.creationTimestamp}' NAME STATUS ROLES AGE VERSION NODETYPE ip-172-20-109-185.ec2.internal Ready master 19d v1.14.1 ip-172-20-58-254.ec2.internal Ready master 19d v1.14.1 ip-172-20-64-178.ec2.internal Ready master 19d v1.14.1 ip-172-20-125-166.ec2.internal Ready node 4d12h v1.14.1 storage ip-172-20-57-197.ec2.internal Ready node 4d12h v1.14.1 storage ip-172-20-71-77.ec2.internal Ready node 4d12h v1.14.1 storage ip-172-20-55-91.ec2.internal Ready node 4d12h v1.14.1 app ip-172-20-75-119.ec2.internal Ready node 4d12h v1.14.1 app ip-172-20-117-251.ec2.internal Ready node 4d12h v1.14.1 app ちなみに、各ノードたちはus-east-1a〜us-east-1cのAZに散らばっています。つまりCephもAZをまたいでクラスターになっています。今の状況を絵で書いてみるとこんな具合です。 前回と同様にstorage nodeにRook-Ceph OperatorとCephをデプロイしてblock用のpoolとstorageclassを作ります。なおこの時に使ったyamlは gist に上げてますのでよろしければどうぞ。 [utubo@tutsunom ~]$ kubectl -n my-rook-ceph get CephBlockPool NAME AGE replicapool 4d1h [utubo@tutsunom ~]$ kubectl -n my-rook-ceph get sc NAME PROVISIONER AGE default kubernetes.io/aws-ebs 19d gp2 (default) kubernetes.io/aws-ebs 19d rbd ceph.rook.io/block 4d1h [utubo@tutsunom ~]$ kubectl -n my-rook-ceph exec -it rook-ceph-operator-f5dd99499-lp2tn -- sh sh-4.2# ceph status ; ceph osd tree sh-4.2# ceph status ; ceph osd tree cluster: id: 99f4030e-4283-4776-8067-b6c028d31beb health: HEALTH_OK services: mon: 3 daemons, quorum a,b,c (age 3d) mgr: a(active, since 3d) osd: 9 osds: 9 up (since 3d), 9 in (since 3d) data: pools: 1 pools, 100 pgs objects: 3 objects, 19 B usage: 9.1 GiB used, 72 GiB / 81 GiB avail pgs: 100 active+clean ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.07910 root default -7 0.02637 host ip-172-20-125-166-ec2-internal 2 ssd 0.00879 osd.2 up 1.00000 1.00000 5 ssd 0.00879 osd.5 up 1.00000 1.00000 8 ssd 0.00879 osd.8 up 1.00000 1.00000 -3 0.02637 host ip-172-20-57-197-ec2-internal 0 ssd 0.00879 osd.0 up 1.00000 1.00000 4 ssd 0.00879 osd.4 up 1.00000 1.00000 6 ssd 0.00879 osd.6 up 1.00000 1.00000 -5 0.02637 host ip-172-20-71-77-ec2-internal 1 ssd 0.00879 osd.1 up 1.00000 1.00000 3 ssd 0.00879 osd.3 up 1.00000 1.00000 7 ssd 0.00879 osd.7 up 1.00000 1.00000 はい、Cephクラスターできてますね。後はアプリなんですが今回はdateをビシバシ叩く奴では面白みがないので、portworxの fio-tools を使ってfioを走らせてみましょう。 このyaml で、20GBのPVをfioのPodにattachして、3分間の4K random writeをかけてみます。ベンチ目的じゃないのでそんなに高い負荷はかけません。 [utubo@tutsunom ~]$ kubectl apply -f my-fiotools-aio-portworx-write.yaml persistentvolumeclaim/fio-data-write created deployment.extensions/fio-tester-write created service/fiotools-write created [utubo@tutsunom ~]$ kubectl get all,pvc,pv NAME READY STATUS RESTARTS AGE pod/fio-tester-write-646f78868f-7fzkj 1/1 Running 0 10s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/fiotools-write NodePort 100.71.144.167 <none> 8000:31182/TCP 9s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/fio-tester-write 1/1 1 1 10s NAME DESIRED CURRENT READY AGE replicaset.apps/fio-tester-write-646f78868f 1 1 1 11s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/fio-data-write Bound pvc-eb9fe2a4-bd8b-11e9-a4d2-0a0909b905da 20Gi RWO rbd 12s NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-eb9fe2a4-bd8b-11e9-a4d2-0a0909b905da 20Gi RWO Delete Bound fio-tools/fio-data-write rbd 12s はい、それではこの間に障害を起こしてみます。 デバイス障害 まずは手始めにデバイス障害を引きおこしてみましょう。ベアメタルならブッコ抜くところですがAWSなんでノードから1つEBSをForce Detachすればいいですかね。 じゃあosd.7に相当するEBSをブッコ抜きます。 [utubo@tutsunom ~]$ kubectl -n my-rook-ceph exec -it rook-ceph-operator-f5dd99499-lp2tn -- sh sh-4.2# ceph status ; ceph osd tree cluster: id: 99f4030e-4283-4776-8067-b6c028d31beb health: HEALTH_WARN 1 osds down Degraded data redundancy: 108/846 objects degraded (12.766%), 38 pgs degraded, 43 pgs undersized too few PGs per OSD (28 < min 30) services: mon: 3 daemons, quorum a,b,c (age 3d) mgr: a(active, since 3h) osd: 9 osds: 8 up (since 2m), 9 in (since 3d) data: pools: 1 pools, 100 pgs objects: 282 objects, 1.0 GiB usage: 12 GiB used, 69 GiB / 81 GiB avail pgs: 108/846 objects degraded (12.766%) 57 active+clean 38 active+undersized+degraded 5 active+undersized io: client: 6.0 MiB/s wr, 0 op/s rd, 1.51k op/s wr ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.07910 root default -7 0.02637 host ip-172-20-125-166-ec2-internal 2 ssd 0.00879 osd.2 up 1.00000 1.00000 5 ssd 0.00879 osd.5 up 1.00000 1.00000 8 ssd 0.00879 osd.8 up 1.00000 1.00000 -3 0.02637 host ip-172-20-57-197-ec2-internal 0 ssd 0.00879 osd.0 up 1.00000 1.00000 4 ssd 0.00879 osd.4 up 1.00000 1.00000 6 ssd 0.00879 osd.6 up 1.00000 1.00000 -5 0.02637 host ip-172-20-71-77-ec2-internal 1 ssd 0.00879 osd.1 up 1.00000 1.00000 3 ssd 0.00879 osd.3 up 1.00000 1.00000 7 ssd 0.00879 osd.7 down 1.00000 1.00000 サヨウナラosd.7。(厳密にはまだCephクラスタからoutになってないのですが10分くらいしたら本当にサヨウナラになります) さあではEBSをForce Detachした時のI/Oを見てみましょう。fioの方で1秒ごとのIOPSとlatencyのログを吐くようにしてるので、それらからグラフを書いてみます。 へえ。6-7msecって意外と良いlatencyでwriteするのね。AZ跨ぎのCephなら10msec以上は覚悟だと思ってたけど。 それは良しとして、左側の赤い点線がEBSをブッコ抜いた瞬間です。ログを見ると50〜52秒の3秒間はIOPSもlatencyも全く記録がありません。latencyのログで53秒目に4000msecほどの記録があるので、4,5秒ほどwriteが止まってたって事ですね。 4,5秒のI/O停止は大抵のアプリケーションでは問題ないでしょう。一般的に、環境によって程度の差はあれ、ストレージで障害が起きると幾ばくかのI/O停止は発生します。I/O完全無停止を保つことは難しい。そのため、アプリに数秒のI/O停止も許容されないような要件がある場合は、例えばデータパス上にI/Oをキャッシュするレイヤーをはさむなどして、I/O停止を吸収できるようなアーキテクチャーのアプリを開発することが必要になります。 ノード障害 次はノード障害を引きおこしてみましょう。先程と同じ用にfioが動いてる間にstorage nodeをstopしちゃいます。 osd.7をもう一回戻して、 ip-172-20-71-77-ec2-internal ノードを落とします。 sh-4.2# ceph status ; ceph osd tree cluster: id: 99f4030e-4283-4776-8067-b6c028d31beb health: HEALTH_WARN 3 osds down 1 host (3 osds) down Degraded data redundancy: 282/846 objects degraded (33.333%), 91 pgs degraded too few PGs per OSD (22 < min 30) 1/3 mons down, quorum a,b services: mon: 3 daemons, quorum a,b (age 40s), out of quorum: c mgr: a(active, since 3d) osd: 9 osds: 6 up (since 27s), 9 in (since 3d) data: pools: 1 pools, 100 pgs objects: 282 objects, 1.0 GiB usage: 12 GiB used, 69 GiB / 81 GiB avail pgs: 282/846 objects degraded (33.333%) 91 active+undersized+degraded 9 active+undersized io: client: 7.7 MiB/s wr, 0 op/s rd, 1.36k op/s wr ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.07910 root default -7 0.02637 host ip-172-20-125-166-ec2-internal 2 ssd 0.00879 osd.2 up 1.00000 1.00000 5 ssd 0.00879 osd.5 up 1.00000 1.00000 8 ssd 0.00879 osd.8 up 1.00000 1.00000 -3 0.02637 host ip-172-20-57-197-ec2-internal 0 ssd 0.00879 osd.0 up 1.00000 1.00000 4 ssd 0.00879 osd.4 up 1.00000 1.00000 6 ssd 0.00879 osd.6 up 1.00000 1.00000 -5 0.02637 host ip-172-20-71-77-ec2-internal 1 ssd 0.00879 osd.1 down 1.00000 1.00000 3 ssd 0.00879 osd.3 down 1.00000 1.00000 7 ssd 0.00879 osd.7 down 1.00000 1.00000 アヒャヒャヒャ。Podはどうなってる? [utubo@tutsunom images]$ kubectl -n my-rook-ceph get pod NAME READY STATUS RESTARTS AGE rook-ceph-agent-8wpx2 1/1 Running 0 4d6h rook-ceph-agent-btcj4 1/1 Running 0 4d6h rook-ceph-agent-fpb9j 1/1 Running 0 4d6h rook-ceph-agent-lcp4q 1/1 Running 0 4d6h rook-ceph-agent-rrknj 1/1 Running 0 4d6h rook-ceph-mgr-a-7f675b44bf-hwf5c 1/1 Running 0 4d3h rook-ceph-mon-a-5f78486c7d-sbsvr 1/1 Running 0 4d3h rook-ceph-mon-b-6986666976-rlkr2 1/1 Running 0 4d3h rook-ceph-mon-d-b9b7968cc-vgvv9 0/1 Pending 0 67s rook-ceph-operator-f5dd99499-lp2tn 1/1 Running 0 3d16h rook-ceph-osd-0-84fd9fc787-tzzzc 1/1 Running 0 4d3h rook-ceph-osd-1-84f67559bf-hcqdq 0/1 Pending 0 67s rook-ceph-osd-2-5987f7774c-4zgjc 1/1 Running 0 4d3h rook-ceph-osd-3-69554f8dd7-gcbk2 0/1 Pending 0 67s rook-ceph-osd-4-5648d65b77-wd78f 1/1 Running 0 4d3h rook-ceph-osd-5-76545dd774-44fx2 1/1 Running 0 4d3h rook-ceph-osd-6-ddb557bc-qkwdk 1/1 Running 0 4d3h rook-ceph-osd-7-796d8d7bff-mfk24 0/1 Pending 0 67s rook-ceph-osd-8-86b7b44f85-hjf2j 1/1 Running 0 4d3h rook-ceph-osd-prepare-ip-172-20-125-166.ec2.internal-pm4n7 0/2 Completed 0 3d16h rook-ceph-osd-prepare-ip-172-20-57-197.ec2.internal-hnrrz 0/2 Completed 0 3d16h rook-discover-4zfs9 1/1 Running 0 4d6h rook-discover-8qgsx 1/1 Running 0 4d6h rook-discover-dll95 1/1 Running 0 4d6h rook-discover-fqcc2 1/1 Running 0 4d6h rook-discover-lxvzp 1/1 Running 0 4d6h ip-172-20-71-77-ec2-internal で動いてた osd.[1,3,7] と mon-d ( mon-c に代わって上がろうとしてる)がPendingになってます。復活しようとしてもScheduleできるノードがないから復活できない感じですね。魂と精神はあるけど生き返れないとはハガレン的。後で人体錬成(ノード追加)するから待っててね。 それではさっきと同じ様にIOの様子を見てみましょう。 やっぱりノード障害はデバイス障害とは違って長くなりますね。ログを見ると75〜100秒までIOPSの記録がないので、ざっくり30秒くらいしてから戻ってます。 結構長くなった理由は、Ceph的な話ですが、osdが無くなるとそのosdをprimaryとしていたplacement group(pg)はread/writeすることができなくなります。そのためmonがpgmapを更新してprimary osdを生きているosdになるようにremapするんですが、remapのpeeringが終わるまではそのpgはI/Oできません。よってpeeringのpgへのfioのwriteが待たされて、結果長いこと待つことになったのではないかと想像します。 また、monが落ちてしまったことで改めてelectionが起きてしまい、pgmap含めcluster mapの更新を始めるのに時間がかかったこともあるのではないかと。 ブロックストレージが30秒停まるというのはおっさんの宇都宮的にはそんなもんかなという気分です。もう時代錯誤かもしれんけど。 Cephのパラメータを調整すればもっと早く戻せるのかとか、たくさん考察できそうですが、ちょっと長くなりそうなのでやめときます。 ちなみに、I/Oが復活してからIOPSとlatencyがほんのり良くなってますよね。これはノードが落ちるまでは三重でレプリカしていたけど、ノードが落ちてからは二重レプリカとなったため、その分1回のwrite requestに対するCephクラスター内でのwrite量が減ったためです。 まとめ そういうわけで今回はRook-Cephのクラスターで障害が起きるとI/Oにどんな影響があるのか調べてみました。 次回はRook-Cephのアーキテクチャを説明していこうと思います。今回RWXできなかったので次回おまけでできたらいいな。 というわけで、今回はここまで。
お疲れ様です!Red Hatの鈴木(tomosuzu)です! 今回は「スプリント計画」です。 下記のリンクからご覧ください。 tomosuzu.com 次回は「インパクトマッピング」を紹介します。 さいごに Red Hatでは、「アイデアをイノベーションに変える、文化・プロセス・技術・実践の場」として、 Open Innovation Labs を提供しています。 デザイン思考やDevOps、アジャイルやリーン開発などをRed Hatのコンサルタントと一緒に取り組むことができます。 過去記事 アジャイル開発のプラクティス一覧をご紹介いたします - 赤帽エンジニアブログ チームの知識共有とコミュニケーションを増やします「ペアプログラミング 」 - 赤帽エンジニアブログ 速い開発速度を保ち、着実に開発を進める「テスト駆動開発」 - 赤帽エンジニアブログ チームの自律性・自主性を高める「社会契約」 - 赤帽エンジニアブログ チームの健康状態を知り、様々な問題に事前に対処「チーム感情の評価」 - 赤帽エンジニアブログ 改善のサイクルを小さく回す「ふりかえり」 - 赤帽エンジニアブログ