[{"categories":["コンテナ技術","DevOps"],"content":"Harbor アクティブスタンバイデプロイ 環境準備 OS: CentOS 8.4 64bit\nHarbor バージョン: harbor-offline-installer-v2.11.1.tgz\nDocker Compose: docker-compose-linux-x86_64\n役割 ホスト名 IP アドレス プライマリ Harbor Harbor01 192.168.8.161 スタンバイ Harbor Harbor02 192.168.8.162 Docker ホスト web01 192.168.8.188 HarborはVMwareのオープンソースエンタープライズDockerレジストリプロジェクトで、公式Docker Registryをベースに、管理UI、ロールベースのアクセス制御（RBAC）、AD/LDAP統合、監査ログなどのエンタープライズ機能を追加しています。Harborの各コンポーネントはDockerコンテナとして構築され、Docker Composeを使用してデプロイされます。\nパート1：プライマリHarborデプロイ（HTTPモード、証明書なし） この方法は社内ネットワーク向けで、SSL証明書なしでHTTPで直接Harborにアクセスします。\n1. Dockerインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 # 既存のyumリポジトリファイルを削除 rm -rf /etc/yum.repos.d/* # Alibaba Cloudミラーからyumリポジトリファイルをダウンロード curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo # Docker CEインストール yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Docker起動とブート時自動起動設定 systemctl enable docker.service --now 2. Dockerミラー設定 1 vim /etc/docker/daemon.json 以下の内容を入力：\n1 2 3 4 5 6 { \u0026#34;registry-mirrors\u0026#34;: [ \u0026#34;https://37564ea7e7cc4824a5049fd666807c27.mirror.swr.myhuaweicloud.com\u0026#34; ], \u0026#34;insecure-registries\u0026#34;: [\u0026#34;http://192.168.8.161\u0026#34;] } 1 2 systemctl daemon-reload systemctl restart docker.service 3. Docker ComposeとHarborインストール 1 2 3 4 5 6 7 8 9 10 # docker-composeとharborオフラインパッケージを/dataに配置 ls /data # docker-compose-linux-x86_64 harbor-offline-installer-v2.11.1.tgz # docker-composeインストール cp /data/docker-compose-linux-x86_64 /usr/local/bin/docker-compose chmod a+x /usr/local/bin/docker-compose # harbor展開 tar -zxvf /data/harbor-offline-installer-v2.11.1.tgz -C /usr/local/ 4. Harbor設定変更 1 2 3 cd /usr/local/harbor/ cp harbor.yml.tmpl harbor.yml vim harbor.yml 主要設定を変更：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 hostname: 192.168.8.161 http: port: 80 # httpsセクション全体をコメントアウト（HTTPモードでは証明書不要） #https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path harbor_admin_password: Harbor12345 data_volume: /images 他の設定はデフォルトのままにします。\n5. インストール実行 1 ./install.sh インストール後、ブラウザで http://192.168.8.161 にアクセスし、admin / Harbor12345でログイン。\n6. ユーザーとプロジェクトの作成 Harbor Web UIでuser1を作成：\nuser1でログイン：\nuser1として新しいプロジェクト（例：openssh）を作成：\n7. イメージのプッシュとプルテスト Dockerホスト（web01）で作業：\n1 2 3 4 5 6 7 8 9 10 11 # Harborにログイン docker login 192.168.8.161 Username: user1 Password: # Login Succeeded # イメージにタグ付け docker tag nginx:latest 192.168.8.161/openssh/nginx:latest # Harborにプッシュ docker push 192.168.8.161/openssh/nginx:latest プッシュ成功後、Harborでイメージを確認：\n1 2 3 # ローカルイメージを削除して再度プル docker image rm -f 192.168.8.161/openssh/nginx:latest docker pull 192.168.8.161/openssh/nginx:latest プル後、Harborにダウンロード回数+1が表示：\nパート2：スタンバイHarborデプロイ スタンバイのデプロイはプライマリと同一で、hostnameをスタンバイのIPに変更するだけです。\n1 vim /usr/local/harbor/harbor.yml 1 hostname: 192.168.8.162 デプロイ後、http://192.168.8.162 にアクセスしてuser2を作成：\nスタンバイHarborにuser2でログイン：\nパート3：アクティブスタンバイレプリケーション設定 1. プライマリにレプリケーションターゲットを作成 プライマリHarborにadminでログインし、管理 → レジストリに移動して新しいターゲットを作成：\nスタンバイ情報を入力：\nエンドポイントURL：http://192.168.8.162 アクセスID / アクセスキー：user2の資格情報 作成成功：\n2. レプリケーションポリシー作成 管理 → レプリケーションに移動して新しいポリシーを作成：\n宛先レジストリ：Harbor02を選択 モード：イベント駆動（または他のモード） 3. 同期結果の確認 Dockerホストからプライマリにさらにイメージをプッシュ：\n1 2 3 4 5 docker tag httpd:2.4 192.168.8.161/openssh/httpd:2.4 docker push 192.168.8.161/openssh/httpd:2.4 docker tag mysql:5.7 192.168.8.161/openssh/mysql:5.7 docker push 192.168.8.161/openssh/mysql:5.7 プライマリイメージを確認：\nスタンバイイメージを確認（自動同期済み）：\nスタンバイにプライマリから同期されたイメージが表示されれば、アクティブスタンバイレプリケーションが成功しています。\n注意：レプリケーション設定前にすでに存在していたイメージは手動で同期する必要があります。\nパート4：HTTPS有効化（自己署名証明書） 本番環境やパブリックネットワークではHTTPSを推奨します。以下は自己署名証明書の完全なワークフローです。\n1. CAとサーバー証明書の生成 Harborサーバーで実行：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 mkdir -p /data/cert \u0026amp;\u0026amp; cd /data/cert # CA秘密鍵生成 openssl genrsa -out ca.key 4096 # CA証明書生成（10年有効） openssl req -x509 -new -nodes -sha512 -days 3650 \\ -subj \u0026#34;/C=CN/CN=HarborRootCA\u0026#34; \\ -key ca.key \\ -out ca.crt # サーバー秘密鍵生成 openssl genrsa -out harbor.key 4096 # サーバー証明書リクエスト生成（CN = Harbor IPまたはドメイン） openssl req -sha512 -new \\ -subj \u0026#34;/C=CN/CN=192.168.8.161\u0026#34; \\ -key harbor.key \\ -out harbor.csr 2. 証明書拡張情報設定 SAN（Subject Alternative Name）を含む v3.ext ファイルを作成：\n1 2 3 4 5 6 7 8 9 10 cat \u0026gt; v3.ext \u0026lt;\u0026lt;-EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] IP.1=192.168.8.161 EOF IP.1 はHarborの実際のアクセスアドレスと一致する必要があります。一致しない場合、Dockerクライアントが証明書ドメイン不一致エラーを報告します。\n3. サーバー証明書に署名 1 2 3 4 5 openssl x509 -req -sha512 -days 3650 \\ -extfile v3.ext \\ -CA ca.crt -CAkey ca.key -CAcreateserial \\ -in harbor.csr \\ -out harbor.crt 4. Harbor設定でHTTPS有効化 1 vim /usr/local/harbor/harbor.yml httpsセクションのコメントを外し、証明書パスを更新：\n1 2 3 4 5 6 hostname: 192.168.8.161 https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key hostnameは v3.ext の IP.1 と一致する必要があります。\n5. Harbor再デプロイ 1 2 3 4 cd /usr/local/harbor/ docker-compose down ./prepare docker-compose up -d 注意：docker-compose down -v を使用しないでください。-v は名前付きボリュームを削除し、Harborデータベースとユーザーデータが失われます。\nデプロイ後、https://192.168.8.161 でアクセス。\n6. Dockerクライアントの証明書信頼設定 イメージのプッシュ/プルが必要なすべてのマシンで実行：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 証明書ディレクトリ作成（名前はHarbor IPまたはドメイン） mkdir -p /etc/docker/certs.d/192.168.8.161 # CA証明書をそのディレクトリにコピー # 方法1：Harborサーバーからscp scp root@192.168.8.161:/data/cert/ca.crt /etc/docker/certs.d/192.168.8.161/ # 方法2：手動でca.crtファイルの内容をコピー # Docker再起動 systemctl restart docker # ログインテスト docker login 192.168.8.161 # adminとパスワードを入力、\u0026#34;Login Succeeded\u0026#34;が表示されれば成功 パート5：FAQ Q：HTTPモードとHTTPSモードを切り替えられますか？\nはい。harbor.yml のhttpsセクションを変更後、./install.sh を再実行してください。HTTPからHTTPSへの切り替えには証明書の事前生成が必要です。HTTPSからHTTPへの切り替えにはhttpsセクションをコメントアウトしてください。\nQ：DockerクライアントがHTTPS Harborへのログイン時に「x509: certificate relies on legacy Common Name field」エラーを報告する場合\n証明書にSAN（Subject Alternative Name）が含まれていないためです。v3.ext に IP.1=\u0026lt;Harbor IP\u0026gt; が含まれており、-extfile v3.ext で署名していることを確認してください。\nQ：レプリケーション失敗のトラブルシューティング方法は？\nプライマリとスタンバイ間のネットワーク接続、ターゲットレジストリの資格情報、対象ユーザーのターゲットプロジェクトへの書き込み権限を確認してください。\n","date":"2026-08-04","description":"","objectID":"/ja/posts/harbor-master-slave/","readingTime":3,"tags":["Harbor","Docker","イメージレジストリ","レプリケーション","HTTPS"],"title":"Harbor アクティブスタンバイデプロイ：インストールからHTTPS・レプリケーションまで","url":"/ja/posts/harbor-master-slave/","wordCount":585},{"categories":["OpenStack"],"content":"一、OpenStack のコアコンポーネントとその役割 1. HORIZON —— 統一グラフィカル管理コンソールサービス コア機能: Web ベースの Dashboard グラフィカル管理コンソールを提供し、クラウド管理者と一般テナントがクラウドリソースを視覚的に割り当て・監視できるようにする。 2. NOVA —— コンピュートリソース管理サービス コア機能: クラウド環境の仮想化コンピュートリソース（nova-compute）を管理・設定する。 役割分担: Controller 制御ノード: nova-api、nova-scheduler、nova-conductor などのスケジューリングサービスを実行する。ユーザーがクラウドインスタンス作成を要求すると、nova-api が要求を受け取り解析し、nova-scheduler がポリシーに基づき最適なコンピュートノードを選択して負荷を分散する。 Compute コンピュートノード: クラウドインスタンスを実際に実行するワーカーノード（KVM、VMware ESXi、Xen などの異種ハイパーバイザーに対応）。 制御ノードの高可用性とパフォーマンスのボトルネック: 制御ノードはすべての API ゲートウェイ、データベース、メッセージキューを担っており、高可用性とパフォーマンスの負荷が生じる。 3. GLANCE —— イメージサービス コア機能: OS イメージの発見・登録・検索・ストレージ管理を担当する。 一般的なディスクイメージ形式: KVM で一般的な形式: qcow2（シンプロビジョニングとコピーオンライト COW をサポート）; VMware で一般的な形式: vmdk。 デプロイ推奨: 通常、高可用性を実現するために制御ノード上に統合・併置してデプロイする。 4. SWIFT —— オブジェクトストレージサービス コア機能: 高可用性・分散・結果整合性のあるオブジェクトストレージサービス（Object Storage）を提供し、静的で非構造化のデータ、クラウドインスタンスのシステムイメージ、データのフルバックアップなどに特化している。 5. NEUTRON —— ソフトウェア定義ネットワーク（SDN） コア機能: クラウド環境でネットワーク・アズ・ア・サービスを提供し、仮想ルーター、スイッチ、セキュリティグループ、フローティング IP、ノード間トラフィックの接続を管理する。 ネットワーク技術: VLAN、VXLAN、Geneve、分散仮想ルーティング（DVR）を全面サポート; ハードウェア SDN モード: 本番環境では通常 2 台の専用ネットワークノードを配置してアクティブ・アクティブまたはアクティブ・スタンバイクラスタを構築する。 6. CINDER —— ブロックストレージサービス コア機能: クラウドインスタンス向けの永続的なブロックストレージ（クラウドディスク）を提供し、動的なアタッチ・デタッチ・スナップショット・容量拡張が可能。 バックエンド連携能力: 従来型ストレージアレイとの連携: Huawei OceanStor、IBM、EMC などのハイエンドハードウェアストレージ; オープンソース分散ストレージとの連携: Ceph RBD、GlusterFS など。 バックエンドの仕組み: ユーザーがクラウドディスクを申請すると、Cinder は指示をバックエンドストレージシステムに下位伝達し、本質的に物理／分散ストレージ内に LUN を切り出してマッピングする。 比較説明: オブジェクトストレージ（Baidu Netdisk、Swift、S3 など）はブロックデバイスとして直接フォーマットしてクラウドインスタンスのファイルシステムとしてマウントできないが、Cinder ブロックデバイスは直接フォーマットしてマウントして利用できる。 7. HEAT —— オーケストレーションサービス コア機能: 宣言型テンプレート（HOT テンプレートまたは AWS CloudFormation 形式）に基づき、グラフィカルなオーケストレーションやスクリプトで複数の VM、データベースクラスタ、ネットワークトポロジ、監視ポリシーをワンクリックで自動一括デプロイする。 8. CEILOMETER —— メータリング・監視サービス コア機能: 物理リソースと仮想リソースのパフォーマンス指標、稼働時間、使用量を収集する。 パブリッククラウドシナリオ: API 呼び出し回数、ネットワーク送信量、コンピュート時間を記録し、課金システムと連携する; プライベートクラウドシナリ오: テナントのクォータ水位を監視し、リソースの過剰利用や遊休を特定してキャパシティプランニングを支援する。 9. KEYSTONE —— 統一認証・認可サービス コア機能: OpenStack 全体のセキュリティの礎石であり、プラットフォーム全体のテナント（Project）、ユーザー（User）、ロール（Role）、サービスカタログ、トークン認証を担当する。 エンタープライズ向けアイデンティティフェデレーション: 企業の既存の Windows Active Directory (AD) や Linux OpenLDAP とシームレスに統合し、エンタープライズグレードの統一アカウント単一サインオン（SSO）を実現する; フロー承認と権限分離（Huawei Cloud の例）: クラウドインスタンスの多段階申請・承認ワークフローをサポート（最大 5 段階の承認）; 「三権分立」のセキュリティ原則を徹底（セキュリティ責任者、システム管理者、監査員が権限を分離して管理）; 顧客の自社開発 OA/BPM 承認フローシステムとの連携をサポート。 コアコンポーネント早見表： コンポーネント名 コード名 コアサービス機能 Horizon Dashboard 統一 Web グラフィカル管理コンソール Nova Compute コンピュートリソースのライフサイクルとインスタンススケジューリング管理 Glance Image 仮想マシンイメージのストレージとバージョン登録 Swift Object 大規模非構造化オブジェクトストレージサービス Neutron Network ソフトウェア定義ネットワーク（SDN）、ルーティングとセキュリティグループ管理 Cinder Block クラウドインスタンスの永続ブロックストレージ（クラウドディスク）管理 Heat Orchestration インフラストラクチャ・アズ・コード（IaC）の複数リソーススタックオーケストレーション Ceilometer Metering リソース使用量統計、監視メータリング、クォータ分析 Keystone Identity 統一認証、認可トークン、サービスカタログ管理 二、OpenStack デプロイ計画（Victoria 版） 1. デプロイ方式の比較 オープンソースの手動デプロイ: コンポーネントを個別にコンパイル・設定する—煩雑で複雑であり、通常は基盤メカニズムの深い学習向け; ツールによる自動化デプロイ: Ansible デプロイ（OpenStack-Ansible、Kolla-Ansible など）; Packstack デプロイ: Red Hat が公開する Puppet ベースの自動化迅速デリバリーツール（本実践で採用）; 2. クラスタノード仕様とネットワーク計画 （1）Controller 制御ノード（1 台） 搭載コンポーネント: API サービス: nova-api、cinder-api、glance-api、neutron-server など; 基盤サービス: MariaDB / MySQL、RabbitMQ メッセージキュー、Memcached、Keystone; ネットワーク・管理サービス: ネットワークノードの外部ルーティング転送、ローカル YUM キャッシュ、Chrony 時刻同期サーバー。 システム構成要件: CPU: 4 vCPU 以上 メモリ: 4GB 以上 ディスク: 100GB の空きディスク容量 NIC: 3 枚のネットワークカード（NIC 1 はインターネット接続用ブリッジモード、NIC 2 と NIC 3 はホストオンリー mode で内部トラフィック） IP アドレス計画: 内部管理 IP: 192.168.100.10 外部アクセス IP: 192.168.10.10 （2）Compute コンピュートノード（1 台） 搭載コンポーネント: nova-compute、ネットワーク L2 Agent（Open vSwitch Agent） システム構成要件: CPU: 4 vCPU 以上 メモリ: 8GB 以上（最低 4GB） ディスク: 100GB のディスク容量 NIC: 3 枚のネットワークカード（すべてホストオンリー mode） IP アドレス計画: Compute: 192.168.100.11 （3）YUM リポジトリサーバー + Chrony 時刻同期サーバー（1 台） システム構成要件: CPU: 2 vCPU メモリ: 2GB NIC: 2 枚（1 枚はインターネットにブリッジして公開時刻同期と上流リポジトリ用、もう 1 枚はホストオンリーで内部ノードへ提供） IP アドレス計画: 外部 IP: 192.168.10.11 内部 IP: 192.168.100.20 環境ダウングレード説明: パーソナルコンピュータのハードウェア資源が限られている場合、最小構成を 2 台の VM に圧縮できる（制御ノードを YUM ソースと時刻同期サーバーとして兼用し、もう 1 台をコンピュートノードとする）。注意: 各ノードのシステム時刻は高度に一致していなければならず、時刻ドリフトは 5 分を超えてはならない。さもないと Keystone ハンドシェイクとメッセージキュー通信が全面的に失敗する。\n三、OpenStack 自動化デプロイ実践手順 フェーズ1：YUM リポジトリサーバーと Chrony 時刻同期サーバーの構築 1. ネットワークインターフェースの設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # 1. 内部通信用 NIC ens160 を設定 [root@Cloud ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens160 TYPE=Ethernet BOOTPROTO=none NAME=ens160 DEVICE=ens160 ONBOOT=yes IPADDR=192.168.100.20 PREFIX=24 # 2. インターネット接続用 NIC ens192 を設定（公開 NTP 同期用） [root@Cloud ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens192 TYPE=Ethernet BOOTPROTO=none NAME=ens192 DEVICE=ens192 ONBOOT=yes PROXY_METHOD=none BROWSER_ONLY=no IPADDR=192.168.10.11 PREFIX=24 GATEWAY=192.168.10.1 DNS1=192.168.10.1 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=no UUID=03da7500-2101-c722-2438-d0d006c28c73 # NIC を再起動して設定を有効化 [root@Cloud ~]# nmcli connection down ens160 ; nmcli connection up ens160 Connection \u0026#39;ens160\u0026#39; successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1) Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4) [root@Cloud ~]# nmcli connection down ens192 ; nmcli connection up ens192 Connection \u0026#39;ens192\u0026#39; successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3) Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5) 2. ローカル CD-ROM YUM リポジトリの設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@Cloud ~]# cd /etc/yum.repos.d/ [root@Cloud yum.repos.d]# mkdir bak [root@Cloud yum.repos.d]# mv CentOS-Linux-* bak/ # OS インストール ISO をマウント mount /dev/cdrom /media/ # CD-ROM ローカルリポジトリ設定ファイルを作成 [root@Cloud ~]# cat \u0026gt; /etc/yum.repos.d/dvd.repo \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; \u0026gt; [BaseOS] \u0026gt; name=BaseOS \u0026gt; baseurl=file:///media/BaseOS \u0026gt; gpgcheck=0 \u0026gt; \u0026gt; [AppStream] \u0026gt; name=AppStream \u0026gt; baseurl=file:///media/AppStream \u0026gt; gpgcheck=0 \u0026gt; EOF 3. Chrony 時刻同期サーバーの設定 OpenStack はノード間の時刻同期に対する要求が極めて厳しいため、まず時刻ソースを設定する:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # /etc/chrony.conf を編集 [root@Cloud ~]# vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). pool ntp.tencent.com iburst # Allow NTP client access from local network. allow 192.168.100.0/24 # Serve time even if not synchronized to a time source. local stratum 10 # 時刻同期サービスを再起動して検証 [root@Cloud ~]# systemctl restart chronyd.service [root@Cloud ~]# chronyc sources 210 Number of sources = 1 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 106.55.184.199 2 6 17 2 -224us[ -144us] +/- 54ms # ファイアウォールと SELinux を無効化 [root@Cloud ~]# systemctl disable firewalld.service --now [root@Cloud ~]# setenforce 0 [root@Cloud ~]# sed -i \u0026#39;s/^SELINUX=.*/SELINUX=disabled/\u0026#39; /etc/selinux/config 4. httpd によるローカル Web YUM リポジトリの構築 CentOS 8 および OpenStack Victoria ソフトウェアリポジトリを HTTP ミラーソースとして公開し、すべてのクラスタノードが取得できるようにする。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 # 1. Apache Web サービスをインストールして起動 [root@Cloud ~]# yum -y install httpd [root@Cloud ~]# systemctl enable httpd --now # 2. ディレクトリを作成しイメージファイルをマウント [root@Cloud ~]# mkdir /isos [root@Cloud ~]# mkdir -p /var/www/html/centos8 [root@Cloud ~]# mkdir -p /var/www/html/openstack # ベースシステム CD と OpenStack Victoria インストールイメージをマウント [root@Cloud ~]# mount /dev/cdrom /var/www/html/centos8/ [root@Cloud ~]# mount /isos/26-CentOS8-4-OSP-Victoria.iso /var/www/html/openstack/ # 3. マウントを /etc/fstab に永続化 [root@Cloud ~]# vim /etc/fstab /dev/cdrom /var/www/html/centos8 iso9660 defaults 0 0 /isos/26-CentOS8-4-OSP-Victoria.iso /var/www/html/openstack iso9660 defaults 0 0 # 4. HTTP YUM リポジトリファイルを設定 [root@Cloud ~]# vim /etc/yum.repos.d/dvd.repo [BaseOS] name=BaseOS baseurl=http://192.168.100.20/centos8/BaseOS gpgcheck=0 [AppStream] name=AppStream baseurl=http://192.168.100.20/centos8/AppStream gpgcheck=0 [root@Cloud ~]# vim /etc/yum.repos.d/openstack.repo [centos-advanced-virtualization] name=centos-advanced-virtualization baseurl=http://192.168.100.20/openstack/centos-advanced-virtualization gpgcheck=0 [centos-nfv-openvswitch] name=centos-nfv-openvswitch baseurl=http://192.168.100.20/openstack/centos-nfv-openvswitch gpgcheck=0 [centos-rabbitmq-38] name=centos-rabbitmq-38 baseurl=http://192.168.100.20/openstack/centos-rabbitmq-38 gpgcheck=0 [PowerTools] name=PowerTools baseurl=http://192.168.100.20/openstack/PowerTools gpgcheck=0 [centos-ceph-nautilus] name=centos-ceph-nautilus baseurl=http://192.168.100.20/openstack/centos-ceph-nautilus gpgcheck=0 [centos-openstack-victoria] name=centos-openstack-victoria baseurl=http://192.168.100.20/openstack/centos-openstack-victoria gpgcheck=0 [extras] name=extras baseurl=http://192.168.100.20/openstack/extras gpgcheck=0 # 5. 作成した repo ファイルを各制御ノードとコンピュートノードに一括配布 [root@Cloud ~]# scp /etc/yum.repos.d/dvd.repo /etc/yum.repos.d/openstack.repo root@192.168.100.10:/etc/yum.repos.d/ [root@Cloud ~]# scp /etc/yum.repos.d/dvd.repo /etc/yum.repos.d/openstack.repo root@192.168.100.11:/etc/yum.repos.d/ フェーズ2：各クラスタノードのシステム環境初期化 1. Controller 制御ノードの初期化（192.168.100.10） 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 # 1. 管理ネットワーク ens160 を設定 [root@Controller ~]# nmcli connection modify ens160 ipv4.addresses 192.168.100.10/24 ipv4.method manual autoconnect yes [root@Controller ~]# nmcli connection down ens160 ; nmcli connection up ens160 # 2. 外部ネットワーク NIC ens224 を設定 [root@Controller ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens224 TYPE=Ethernet BOOTPROTO=none NAME=ens224 DEVICE=ens224 ONBOOT=yes [root@Controller ~]# nmcli connection reload [root@Controller ~]# nmcli connection modify ens224 ipv4.addresses 192.168.10.10/24 ipv4.gateway 192.168.10.1 ipv4.dns 192.168.10.1 ipv4.method manual autoconnect yes [root@Controller ~]# nmcli connection down ens224 ; nmcli connection up ens224 # 3. Chrony NTP クライアントを設定 [root@Controller ~]# vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). pool 192.168.100.20 iburst [root@Controller ~]# systemctl restart chronyd.service [root@Controller ~]# chronyc sources 210 Number of sources = 1 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.168.100.20 3 6 377 24 -22us[ -46us] +/- 43ms # 4. ホスト名を設定 [root@Controller ~]# hostnamectl set-hostname Controller # 5. ファイアウォールと SELinux を無効化 [root@Controller ~]# systemctl disable firewalld.service --now [root@Controller ~]# setenforce 0 [root@Controller ~]# sed -i \u0026#39;s/^SELINUX=.*/SELINUX=disabled/\u0026#39; /etc/selinux/config # 6. クラスタの /etc/hosts 名前解決を設定 [root@Controller ~]# vim /etc/hosts 192.168.100.10 Controller 192.168.100.11 Compute # 7. デフォルトシステム repo キャッシュを削除 [root@Controller ~]# cd /etc/yum.repos.d [root@Controller yum.repos.d]# mkdir -p bak \u0026amp;\u0026amp; mv CentOS-Linux-* bak/ 2. Compute コンピュートノードの初期化（192.168.100.11） 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 1. 管理ネットワークを設定 [root@Compute ~]# nmcli connection modify ens160 ipv4.addresses 192.168.100.11/24 ipv4.method manual autoconnect yes [root@Compute ~]# nmcli connection down ens160 ; nmcli connection up ens160 # 2. Chrony NTP クライアントを設定 [root@Compute ~]# vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). pool 192.168.100.20 iburst [root@Compute ~]# systemctl enable chronyd.service --now # 3. ホスト名を設定 [root@Compute ~]# hostnamectl set-hostname Compute # 4. ファイアウォールと SELinux を無効化 [root@Compute ~]# systemctl disable firewalld.service --now [root@Compute ~]# setenforce 0 [root@Compute ~]# sed -i \u0026#39;s/^SELINUX=.*/SELINUX=disabled/\u0026#39; /etc/selinux/config # 5. クラスタ hosts 名前解決を設定 [root@Compute ~]# vim /etc/hosts 192.168.100.10 Controller 192.168.100.11 Compute # 6. デフォルトシステム repo を削除 [root@Compute ~]# cd /etc/yum.repos.d [root@Compute yum.repos.d]# mkdir -p bak \u0026amp;\u0026amp; mv CentOS-Linux-* bak/ ⚠️ 重要チェックポイント: この時点で全 VM をシャットダウンし、異常発生時に迅速にロールバックできるよう統一スナップショットを取得することを推奨。\nフェーズ3：Packstack 自動化アンサーファイルデプロイ 1. Packstack デプロイツールのインストール 制御ノード（Controller）で実行:\n1 [root@Controller ~]# yum -y install openstack-packstack 2. デフォルトのアンサーファイルを生成 1 [root@Controller ~]# packstack --gen-answer-file=/root/answers.txt ネットワーク方式の説明: OpenStack Victoria は OVN（Open Virtual Network）と従来の OVS（Open vSwitch）の両方をサポートする。\n3. アンサーファイルのパラメータを精密にカスタマイズ 1 2 # 自動検出された外部 IP を内部管理 IP 192.168.100.10 に統一置換 [root@Controller ~]# sed -i \u0026#39;s/192.168.10.10/192.168.100.10/g\u0026#39; /root/answers.txt /root/answers.txt を編集し、以下のコア設定項目を確認・修正する:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # 1. コンピュートノードクラスタの IP 一覧を指定（カンマ区切り） CONFIG_COMPUTE_HOSTS=192.168.100.11 # 2. Keystone 管理者 root の初期パスワードを設定 CONFIG_KEYSTONE_ADMIN_PW=000000 # 3. Demo テナントネットワークを無効化（本番化規範） CONFIG_PROVISION_DEMO=n # 4. Heat オーケストレーションコンポーネントを有効化 CONFIG_HEAT_INSTALL=y # 5. Neutron コアドライバーとネットワークタイプ設定（ML2 + OVS） CONFIG_NEUTRON_ML2_TYPE_DRIVERS=geneve,flat,vxlan,vlan CONFIG_NEUTRON_ML2_MECHANISM_DRIVERS=openvswitch CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES=vxlan CONFIG_NEUTRON_L2_AGENT=openvswitch # 6. OVS 外部ネットワークブリッジバインディング設定（物理外部 NIC ens224 を関連付け） CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=extnet:br-ex CONFIG_NEUTRON_OVS_BRIDGE_IFACES=br-ex:ens224 # 7. ストレージクォータ容量を事前設定 CONFIG_SWIFT_STORAGE_SIZE=20G CONFIG_CINDER_VOLUMES_SIZE=50G ⚠️ 重要チェックポイント: アンサーファイル修正後、再度すべての VM をシャットダウンしてスナップショットを取得することを推奨。\n4. ワンクリック自動化デプロイの実行 電源投入後、制御ノードでデプロイコマンドを実行:\n1 [root@Controller ~]# packstack --answer-file=/root/answers.txt デプロイスクリプトは Puppet に基づき、全ノードでソフトウェアソース設定、データベースのテーブル作成、メッセージキュークラスタ構築、証明書生成、各コンポーネントの協調統合テストを自動で完了する。終了後、ターミナルに Dashboard ログイン URL と keystonerc_admin 環境変数ファイルのパスを出力する。\n四、Linux システムログ管理と OpenStack トラブルシューティング 1. Linux Rsyslog のログレベルと設定アーキテクチャ Linux システムでは、システムの低層と大部分のサービスのログは rsyslog デーモンによって集中管理される。\n設定ファイルを確認: 1 2 rpm -qc rsyslog # コアのメイン設定ファイル: /etc/rsyslog.conf ログルールの構文解析： 1 サービス種別(Facility).ログレベル(Priority) ログ格納パス 一般的な設定例:\n1 2 3 4 5 6 7 8 9 # 1. システム共通の通常メッセージ: # すべてのサービスの \u0026gt;=info レベルのログを記録するが、メール・認証セキュリティ・ cron ログを除外 *.info;mail.none;authpriv.none;cron.none /var/log/messages # 2. デバッグログ: *.debug /var/log/debug # 3. エラーレベルログ: *.err /var/log/error.log 構文ルールの要点: mail: サービス種別（Facility）; info: ログ優先度レベル; .: 以上（\u0026gt;=） の優先度のログメッセージに一致することを示す; *.info: すべてのサービスの \u0026gt;= info レベルのログが対象ファイルに集約されて書き込まれることを意味する。 リアルタイム動的ログ監視コマンド： 1 2 3 4 5 # システムログの末尾出力を追跡 tail /var/log/messages # リアルタイムでログストリームを継続監視 tail -f /var/log/messages 2. OpenStack カスタムサービスログのトラブルシューティング基準 トラブルシューティング原則: 各コンポーネントは通常独自のカスタムログファイル体系（/var/log/\u0026lt;コンポーネント名\u0026gt;/ 配下）を持つ。コンポーネントが異常の場合、まずそのコンポーネント専用ログを排查し、カスタムログがない場合のみシステム全体ログ /var/log/messages に戻って排查する。\n実践例：Neutron ネットワークサービスの障害特定 デプロイまたは運用中に、仮想ネットワーク作成が失敗したり OVS ポートが起動しなかったりする場合、正規表現マッチングでエラーと警告を直接捕捉できる:\n1 2 3 4 5 # 1. 全 Neutron ログから正規表現でエラーと警告を横断フィルタ tail -f /var/log/neutron/*.log | grep -iE \u0026#39;(err|warn)\u0026#39; # 2. neutron-server コア API サービスログを深く排查し、マッチ項目の前後 3 行のコンテキストを出力: tail -f /var/log/neutron/server.log | grep -iE -A3 -B3 \u0026#39;(err|warn)\u0026#39; パラメータ説明:\n-i: 大文字小文字を無視; -E: 拡張正規表現マッチング (err|warn) を有効化; -A 3 (After): マッチ行の後 3 行を出力; -B 3 (Before): マッチ行の前 3 行を出力。 ","date":"2026-10-06","description":"","objectID":"/ja/posts/openstack-core-architecture-deployment/","readingTime":8,"tags":["OpenStack","クラウドコンピューティング","自動化デプロイ","Packstack","Victoria"],"title":"OpenStack クラウド OS：コアアーキテクチャと自動化デプロイ","url":"/ja/posts/openstack-core-architecture-deployment/","wordCount":1589},{"categories":["OpenStack"],"content":"Cinder のボリューム作成とアタッチの構成 ボリューム作成の流れは cinder ノード（コントローラーノード）が提供し、ボリュームのマウントは nova が提供します\nローカル LVM + iSCSI ボリュームストレージの設定 answers.txt 応答ファイルで cinder ボリュームを作成するよう指定します。実験環境では専用のストレージ機器を用意できないため、システムはローカル LVM を cinder ストレージとして採用します システムは既定で cinder-volumes ボリュームグループを 50G で作成します（ユーザーが手動で指定）\nこのボリュームグループはコントローラーノード上に作成されます\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [root@Controller ~]# vgdisplay --- Volume group --- VG Name cl System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 3 Open LV 3 Max PV 0 Cur PV 1 Act PV 1 VG Size \u0026lt;99.00 GiB PE Size 4.00 MiB Total PE 25343 Alloc PE / Size 25343 / \u0026lt;99.00 GiB Free PE / Size 0 / 0 VG UUID K2c9TX-MlXI-k9Ga-CPPm-3zuu-WNoK-mRuUEZ --- Volume group --- VG Name cinder-volumes System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size \u0026lt;51.50 GiB PE Size 4.00 MiB Total PE 13183 Alloc PE / Size 12551 / \u0026lt;49.03 GiB Free PE / Size 632 / \u0026lt;2.47 GiB VG UUID nXhaeU-1PwG-is18-Ef2N-cK5R-9LRk-3ksn1k /etc/cinder/cinder.conf で LVM ドライバを呼び出し、作成したボリュームグループを認識させます このコントローラーノードを ISCSI ストレージ（target）とみなし、ユーザーが作成したボリュームを ISCSI で compute ノードに共有します ユーザーが 2G のクラウドディスクを作成すると、システムは自動的に LVM ドライバを呼び出してボリュームグループ内に 2G の LV を作成します\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 [root@Controller ~]# lvdisplay --- Logical volume --- LV Path /dev/cl/swap LV Name swap VG Name cl LV UUID f9Aqve-GgxT-gQNg-v0W0-ogyz-1cJT-WIEOMw LV Write Access read/write LV Creation host, time localhost.localdomain, 2026-06-27 05:28:10 +0800 LV Status available # open 2 LV Size \u0026lt;7.88 GiB Current LE 2016 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:1 --- Logical volume --- LV Path /dev/cl/home LV Name home VG Name cl LV UUID 5f8ntZ-4pxS-yYFl-3BHC-qKaW-pFsi-2ZGkHg LV Write Access read/write LV Creation host, time localhost.localdomain, 2026-06-27 05:28:10 +0800 LV Status available # open 1 LV Size 29.89 GiB Current LE 7653 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:2 --- Logical volume --- LV Path /dev/cl/root LV Name root VG Name cl LV UUID 32JpBQ-Ld4z-0bLU-jHuG-iMRC-WLoO-WtcrnT LV Write Access read/write LV Creation host, time localhost.localdomain, 2026-06-27 05:28:10 +0800 LV Status available # open 1 LV Size \u0026lt;61.23 GiB Current LE 15674 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:0 --- Logical volume --- LV Name cinder-volumes-pool VG Name cinder-volumes LV UUID ughXDw-Fl7B-Mbo9-vsHS-OvMy-Pi60-E2GPaa LV Write Access read/write (activated read only) LV Creation host, time Controller, 2026-07-08 16:03:29 +0800 LV Pool metadata cinder-volumes-pool_tmeta LV Pool data cinder-volumes-pool_tdata LV Status available # open 0 LV Size \u0026lt;48.93 GiB Allocated pool data 0.00% Allocated metadata 10.44% Current LE 12525 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:6 --- Logical volume --- LV Path /dev/cinder-volumes/volume-3561d822-2929-4b47-87c5-25f769f8f44e LV Name volume-3561d822-2929-4b47-87c5-25f769f8f44e VG Name cinder-volumes LV UUID WoSBug-zWc4-wVYn-39xk-MWVw-z3Pj-UOdvok LV Write Access read/write LV Creation host, time Controller, 2026-10-05 15:56:30 +0800 LV Pool name cinder-volumes-pool LV Status available # open 0 LV Size 2.00 GiB Mapped size 0.00% Current LE 512 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:7 ユーザーがこのボリュームをクラウドサーバー web01 にアタッチすると、cinder はストレージ側に指示を送ります。ストレージ側はその LV を compute ホストに共有し、compute ホストがそのディスクを認識して新しい 2G ディスクが生まれ、libvirt が xml ファイルを呼び出してクラウドサーバーに追加します\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [root@Controller ~]# systemctl status target ● target.service - Restore LIO kernel target configuration Loaded: loaded (/usr/lib/systemd/system/target.service; enabled; vendor preset: disabled) Active: active (exited) since Mon 2026-10-05 14:18:51 CST; 1h 30min ago Process: 1873 ExecStart=/usr/bin/targetctl restore (code=exited, status=0/SUCCESS) Main PID: 1873 (code=exited, status=0/SUCCESS) Tasks: 0 (limit: 36406) Memory: 0B CGroup: /system.slice/target.service Oct 05 14:18:50 Controller systemd[1]: Starting Restore LIO kernel target configuration... Oct 05 14:18:51 Controller target[1873]: No saved config file at /etc/target/saveconfig.json, ok, exiting Oct 05 14:18:51 Controller systemd[1]: Started Restore LIO kernel target configuration. [root@Controller ~]# targetcli targetcli shell version 2.1.53 Copyright 2011-2013 by Datera, Inc and others. For help on commands, type \u0026#39;help\u0026#39;. /\u0026gt; ls o- / ......................................................................................................................... [...] o- backstores .............................................................................................................. [...] | o- block .................................................................................................. [Storage Objects: 1] | | o- iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e [/dev/cinder-volumes/volume-3561d822-2929-4b47-87c5-25f769f8f44e (2.0GiB) write-thru activated] | | o- alua ................................................................................................... [ALUA Groups: 1] | | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized] | o- fileio ................................................................................................. [Storage Objects: 0] | o- pscsi .................................................................................................. [Storage Objects: 0] | o- ramdisk ................................................................................................ [Storage Objects: 0] o- iscsi ............................................................................................................ [Targets: 1] | o- iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e ............................................. [TPGs: 1] | o- tpg1 .......................................................................................... [no-gen-acls, auth per-acl] | o- acls .......................................................................................................... [ACLs: 1] | | o- iqn.1994-05.com.redhat:1220933cde3c ...................................................... [1-way auth, Mapped LUNs: 1] | | o- mapped_lun0 ................. [lun0 block/iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e (rw)] | o- luns .......................................................................................................... [LUNs: 1] | | o- lun0 [block/iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e (/dev/cinder-volumes/volume-3561d822-2929-4b47-87c5-25f769f8f44e) (default_tg_pt_gp)] | o- portals .................................................................................................... [Portals: 1] | o- 192.168.100.10:3260 .............................................................................................. [OK] o- loopback ......................................................................................................... [Targets: 0] /\u0026gt; [root@Compute ~]# cat /etc/iscsi/initiatorname.iscsi InitiatorName=iqn.1994-05.com.redhat:1220933cde3c [root@Compute ~]# iscsiadm -m session tcp: [1] 192.168.100.10:3260,1 iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e (non-flash) [root@Compute ~]# vim /etc/libvirt/qemu/instance-00000002.xml \u0026lt;disk type=\u0026#39;block\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;raw\u0026#39; cache=\u0026#39;none\u0026#39; io=\u0026#39;native\u0026#39;/\u0026gt; \u0026lt;source dev=\u0026#39;/dev/sda\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vdb\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;serial\u0026gt;3561d822-2929-4b47-87c5-25f769f8f44e\u0026lt;/serial\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x07\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; ストレージ側の設定\ntargetcli パッケージをインストールし、サービスを起動します 1 2 3 4 5 6 7 8 9 #yum -y install targetcli #systemctl enable target --now #targetcli /\u0026gt; /backstores/block create dev=/dev/sdb1 name=data01 /\u0026gt; /iscsi create iqn.2024.com.storage:disk /\u0026gt; /iscsi/ iqn.2024.com.storage:disk/tpg1/acls create iqn.1994-05.com.redhat:b4ff583759f4 /\u0026gt;/iscsi/ iqn.2024.com.storage:disk /tpg1/luns create data01 /\u0026gt; /iscsi/ iqn.2024.com.storage:disk/tpg1/portals create 192.168.100.10:3260 /\u0026gt; saveconfig ターゲット、業務サーバー、ストレージクライアント 1 2 3 [root@Compute ~]# iscsiadm -m discovery -t st -p 192.168.100.10 [root@Compute ~]# iscsiadm -m node -T iqn.2024.com.storage:disk -p 192.168.100.10:3260 -l #fdisk -l Cinder と NFS ストレージの連携 上の図に従ってネットワークを設計・設定します\n1. NFS ストレージの設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #配置网络 [root@storage ~]# nmcli connection modify ens160 ipv4.addresses 192.168.200.20/24 ipv4.method manual autoconnect yes [root@storage ~]# nmcli connection down ens160 ; nmcli connection up ens160 [root@storage ~]# cd /etc/sysconfig/network-scripts/ [root@storage network-scripts]# cp ifcfg-ens160 ifcfg-ens192 [root@storage network-scripts]# cat ifcfg-ens192 # Generated by parse-kickstart TYPE=Ethernet DEVICE=ens192 ONBOOT=yes BOOTPROTO=none NAME=ens192 [root@storage ~]# nmcli connection reload [root@storage ~]# nmcli connection modify ens192 ipv4.addresses 192.168.8.20/24 ipv4.method manual autoconnect yes [root@storage ~]# nmcli connection down ens192 ; nmcli connection up ens192 #安装配置安装NFS服务 [root@storage ~]# yum install -y nfs-utils rpcbind [root@storage ~]# mkdir /storage [root@storage ~]# cat /etc/exports /storage 192.168.200.0/24(rw,sync,no_root_squash) /storage 192.168.8.0/24(rw,sync,no_root_squash) [root@storage ~]# systemctl enable nfs-server --now [root@storage ~]# systemctl enable rpcbind --now 2. cinder ノードのネットワーク設定（コントローラーノード） 1 2 3 4 5 6 7 8 [root@Controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens192 TYPE=Ethernet NAME=ens192 DEVICE=ens192 ONBOOT=yes IPADDR=192.168.8.10 NETMASK=255.255.255.0 [root@Controller ~]# systemctl restart network 3. コンピュートノードのネットワーク設定 1 2 [root@Compute ~]# nmcli connection modify ens192 ipv4.addresses 192.168.200.10/24 autoconnect yes ipv4.method manual [root@Compute ~]# nmcli connection down ens192 ; nmcli connection up ens192 4. cinder の設定 1 2 3 4 5 6 7 8 9 10 [root@Controller ~]# vim /etc/cinder/cinder.conf 410 default_volume_type=nfs 436 enabled_backends=lvm,nfs666 [nfs666] volume_backend_name=nfsdata volume_driver=cinder.volume.drivers.nfs.NfsDriver nfs_shares_config = /etc/cinder/nfs_shares [root@Controller ~]# cat /etc/cinder/nfs_shares storage:/storage [root@Controller ~]# systemctl restart openstack-cinder-* Cinder ノード\n1 2 [root@Controller ~]# cat /etc/hosts ####额外增加一条记录 192.168.8.20 storage コンピュートノード\n1 2 3 4 5 6 [root@Compute ~]# cat /etc/hosts 192.168.200.20 storage [root@Controller ~]# source keystonerc_admin [root@Controller ~(keystone_admin)]# cinder type-create nfs [root@Controller ~(keystone_admin)]# cinder type-key nfs set volume_backend_name=nfsdata [root@Controller ~(keystone_admin)]# systemctl restart openstack-cinder-* OpenStack の Web 画面でボリュームを作成し、nfs を選択してそのボリュームをクラウドサーバーに関連付けます\nOpenStack の Web 画面でボリュームを作成し、nfs を選択、ソースにイメージを選びます。クラウドサーバー作成時にはソースとして先ほど作成したボリュームを選択します\nクラウドサーバーを作成し終えると 1 つのボリュームが生成されます\n元のクラウドサーバーを削除して再度作成し直すと、このボリュームが利用できるようになります\n","date":"2026-10-05","description":"","objectID":"/ja/posts/openstack-cinder-block-storage/","readingTime":7,"tags":["OpenStack","Cinder","ブロックストレージ","LVM","iSCSI","NFS"],"title":"OpenStack Cinder ブロックストレージ詳細解説：ローカル LVM + iSCSI ボリュームと NFS バックエンド連携","url":"/ja/posts/openstack-cinder-block-storage/","wordCount":1337},{"categories":["OpenStack"],"content":"Keystone サービス OpenStack のマルチドメイン対応\n1 2 [root@Controller ~]# vim /etc/openstack-dashboard/local_settings OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True システム内の全サービスを一覧表示\n1 [root@Controller ~(keystone_admin)]# openstack service list Keystone アドレスと API インターフェース\n1 OS_AUTH_URL=http://192.168.100.10:5000/v3 全てのサービスは Keystone のアドレスを知っています。ユーザートークンが有効かを Keystone に検証してもらう必要があるためです Keystone は全てのサービスのアドレスを知っています。全てのサービスは作成時に Keystone へ登録を行うためです エンドポイントアドレス\n1 [root@Controller ~(keystone_admin)]# openstack endpoint list 各サービスには 3 つのエンドポイントアドレスがあり、これら 3 つの URL は同じでも異なっていても構いません\npublic url — 外部ユーザーがアクセスする URL アドレス\nadmin url — 管理者がアクセスする URL アドレス\ninternal url — 内部コンポーネント間でアクセスする URL アドレス\nクラウドサーバー提供の流れ\nユーザーは Keystone にユーザー名とパスワードを送信してリクエストします。認証が成功すると Keystone はトークンを発行し、ユーザーはそのトークンを使って nova-api にクラウドサーバー作成リクエストを送ります nova-api は Keystone に助けを求め、そのトークンが有効かどうかを検証してもらい、成功すれば結果が返されます nova-api はリクエストを nova-compute ホストに送信します nova-compute ホストはユーザーのリクエスト情報に基づいてクラウドサーバーを作成し、結果を nova-api に返します nova-api は結果をユーザーに返します。クラウドサーバーの作成が完了し、そのホスト情報はデータベースに記録されます nova-api にサーバー作成リクエストを送る際、私は nova-api のアドレスを知りません。しかし Keystone のアドレスは知っています。Keystone に nova-api のアドレスを問い合わせます。Keystone は全サービスのエンドポイントアドレスを保持しているため、私は Keystone のアドレスだけ知っていればよいのです。以下は Keystone のアドレスを調べ、そこから他のアドレスを引く方法です。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 [root@Controller ~(keystone_zlm)]# grep -E \u0026#34;^connection\\s*=.*keystone\u0026#34; /etc/keystone/*.conf /etc/keystone/keystone.conf:connection=mysql+pymysql://keystone_admin:c3fa63522e1f4586@192.168.100.10/keystone # 用户名：keystone_admin # 密码：c3fa63522e1f4586 [root@Controller ~(keystone_zlm)]# mysql -u keystone_admin -p -D keystone Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 15494 Server version: 10.3.27-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [keystone]\u0026gt; SELECT s.type AS service_type, -\u0026gt; e.interface, -\u0026gt; e.url -\u0026gt; FROM endpoint e -\u0026gt; JOIN service s ON e.service_id = s.id -\u0026gt; ORDER BY s.type, e.interface; +----------------+-----------+--------------------------------------------------+ | service_type | interface | url | +----------------+-----------+--------------------------------------------------+ | alarming | admin | http://192.168.100.10:8042 | | alarming | internal | http://192.168.100.10:8042 | | alarming | public | http://192.168.100.10:8042 | | cloudformation | admin | http://192.168.100.10:8000/v1 | | cloudformation | internal | http://192.168.100.10:8000/v1 | | cloudformation | public | http://192.168.100.10:8000/v1 | | compute | admin | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | compute | internal | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | compute | public | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | identity | admin | http://192.168.100.10:5000 | | identity | internal | http://192.168.100.10:5000 | | identity | public | http://192.168.100.10:5000 | | image | admin | http://192.168.100.10:9292 | | image | internal | http://192.168.100.10:9292 | | image | public | http://192.168.100.10:9292 | | metering | admin | http://192.168.100.10:8777 | | metering | internal | http://192.168.100.10:8777 | | metering | public | http://192.168.100.10:8777 | | metric | admin | http://192.168.100.10:8041 | | metric | internal | http://192.168.100.10:8041 | | metric | public | http://192.168.100.10:8041 | | network | admin | http://192.168.100.10:9696 | | network | internal | http://192.168.100.10:9696 | | network | public | http://192.168.100.10:9696 | | object-store | admin | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | object-store | internal | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | object-store | public | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | orchestration | admin | http://192.168.100.10:8004/v1/%(tenant_id)s | | orchestration | internal | http://192.168.100.10:8004/v1/%(tenant_id)s | | orchestration | public | http://192.168.100.10:8004/v1/%(tenant_id)s | | placement | admin | http://192.168.100.10:8778/placement | | placement | internal | http://192.168.100.10:8778/placement | | placement | public | http://192.168.100.10:8778/placement | | volumev2 | admin | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev2 | internal | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev2 | public | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev3 | admin | http://192.168.100.10:8776/v3/%(tenant_id)s | | volumev3 | internal | http://192.168.100.10:8776/v3/%(tenant_id)s | | volumev3 | public | http://192.168.100.10:8776/v3/%(tenant_id)s | +----------------+-----------+--------------------------------------------------+ 39 rows in set (0.001 sec) MariaDB [keystone]\u0026gt; SELECT s.type AS service_type, -\u0026gt; e.interface, -\u0026gt; e.url -\u0026gt; FROM endpoint e -\u0026gt; JOIN service s ON e.service_id = s.id -\u0026gt; WHERE e.interface = \u0026#39;public\u0026#39; -\u0026gt; ORDER BY s.type; +----------------+-----------+--------------------------------------------------+ | service_type | interface | url | +----------------+-----------+--------------------------------------------------+ | alarming | public | http://192.168.100.10:8042 | | cloudformation | public | http://192.168.100.10:8000/v1 | | compute | public | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | identity | public | http://192.168.100.10:5000 | | image | public | http://192.168.100.10:9292 | | metering | public | http://192.168.100.10:8777 | | metric | public | http://192.168.100.10:8041 | | network | public | http://192.168.100.10:9696 | | object-store | public | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | orchestration | public | http://192.168.100.10:8004/v1/%(tenant_id)s | | placement | public | http://192.168.100.10:8778/placement | | volumev2 | public | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev3 | public | http://192.168.100.10:8776/v3/%(tenant_id)s | +----------------+-----------+--------------------------------------------------+ 13 rows in set (0.000 sec) MariaDB [keystone]\u0026gt; OpenStack デプロイ時のサービス作成\nデータベースに入り、データベース（例: glance）を作成します データベースユーザー glance を作成し、glance データベース内の全テーブルに対する ALL（参照・追加・更新・削除）権限を付与します glance サービスを作成し、glance-api のアドレス（エンドポイントアドレス）をデータベースに登録します ユーザーが glance-api にアクセスする必要がある場合、Keystone にリクエストを送り、Keystone データベースから glance api のエンドポイントアドレスを検索します\n1 2 #示例 如果将zlm用户加入admin角色，那他就拥有了admin角色权限 [root@Controller ~(keystone_admin)]# openstack role add --user zlm --project LMandMY_HOME admin ユーザーが nova-api にリクエストを送ると、nova-api は Keystone にユーザー身份とトークンの有効期限を検証させます。ユーザーにクラウドサーバー作成権限があるかは判定しません。権限の有無は各サービスのポリシーファイルに依存します\n1 2 3 4 5 6 7 8 9 [root@Controller nova]# cd /etc/openstack-dashboard/ [root@Controller openstack-dashboard]# ls cinder_policy.json keystone_policy.json neutron_policy.json nova_policy.json glance_policy.json local_settings nova_policy.d [root@Controller nova(keystone_user)]# cp /etc/openstack-dashboard/glance_policy.json /etc/glance/policy.json [root@Controller nova(keystone_user)]# openstack image create --container-format bare --disk-format qcow2 --file /root/cirros-0.3.5-x86_64-disk.img --public test2 [root@Controller nova(keystone_user)]# chgrp glance /etc/glance/policy.json [root@Controller nova(keystone_user)]# systemctl restart openstack-glance-api.service Nova サービス コントローラーノード\nnova-api モジュール\nnova-scheduler モジュール\nnova-conductor モジュール\nnova-novncproxy モジュール\nコンピュートノード\nnova-compute モジュール\nnova-api\n外部に公開する REST インターフェースの処理を担当\n渡されたパラメーターの妥当性検証と制約チェックを行います\nリクエストされたリソースのクォータ（quota）を検証し予約します\nリソースの作成・更新・削除・照会など\n仮想マシンのライフサイクルの入口\n水平方向にスケールアウトしてデプロイ可能\nnova-conductor\nnova-compute のデータベース直接アクセスを切り離します。ユーザーがクラウドサーバーの作成を申請し作成が成功すると、nova-conductor モジュールがクラウドサーバー情報をデータベースに書き込みます\ndatabase — そのコンポーネントに関連する情報（クラウドサーバー情報、イメージ情報、ネットワーク情報など）を保存します\nnova-scheduler\nOpenStack 環境に複数の Compute ノードがある場合、ユーザーがクラウドサーバーを作成すると nova-scheduler モジュールが各 compute ホストの重みに基づいて、そのサーバーをどのコンピュートノードで動かすかを決定します\nHAProxy がロードバランシングを提供します。ユーザーが nova-api にアクセスすると、リクエストはまず HAProxy に渡され、各 nova-api の負荷状況に応じてどの API ノードに送るかが決定されます\nMQ — Message Queue（メッセージキュー）\n1 つのコンポーネントが複数のモジュールを持つ場合、モジュール間のやり取りはメッセージキューを経由して輻輳制御などを行います\n1000 人のユーザーが nova-api にリクエストを送った場合\nnova-api はリクエストを nova-compute に送信します\nnova-api はこれら 1000 件のリクエストをメッセージキューに送り、メッセージキューは各 compute ホストのメッセージ消費状況と処理進捗に応じて、それらを順序立てて nova-compute ノードに配信して処理させます\nnova-compute\n実際に仮想マシンを動作させるモジュール\nnova-novncproxy\n動作原理：nova-compute ホストは稼働中の仮想マシンごとに VNC Server のポートを 1 つ開きます\nnova-compute ホストはそのポートを外部に公開してはいけません。公開するとインターネット上のホストがそのポートと仮想マシンにアクセスできてしまいます\nこの問題を解決するため、コントローラーノード上で nova-novncproxy サービスを起動して外部に提供します。ユーザーがその仮想マシンのコンソールにアクセスすると、まず nova-novncproxy にリクエストが送られ、提供された情報（仮想マシンの UUID、トークンなど）からその仮想マシンがどの nova-compute 上で動いているかを検索し、その Compute ホストへリクエストを転送します。\nVNC で仮想マシンを開く仕組み\nvncserver — 5900 番ポート\nvncviewer — vncviewer\nクライアントに vncviewer をインストールする必要はなく、その機能はブラウザの HTML に組み込まれています（noVNC プロトコル）\nGlance と Swift サービス 一、クラウドサーバーのデプロイ：\nユーザーがクラウドサーバーのデプロイ指令を送り検証を通過すると、nova-compute ホストは glance イメージサーバーからイメージをローカル（クラウドサーバーはローカルにデプロイ）にダウンロードします — /var/lib/nova/instances/_base/\nクラウドサーバーが起動すると差分ディスクが生成され、新しく書き込まれたデータはその差分ディスクに保存されます\n実験：glance イメージを glance のローカルディスクではなく Swift オブジェクトストレージに保存する\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@Controller ~]# cd /etc/glance/ [root@Controller glance]# cp glance-api.conf glance-api.conf.bak [root@Controller ~]# vim /etc/glance/glance-api.conf 3057 stores=file,http,swift 3111 default_store=swift 3982 swift_store_region = RegionOne 4032 swift_store_endpoint_type = publicURL 4090 swift_store_container = public 4118 swift_store_large_object_size = 5120 4142 swift_store_large_object_chunk_size = 100 4160 swift_store_create_container_on_put = True 4182 swift_store_multi_tenant = True 4230 swift_store_admin_tenants = services 4382 swift_store_auth_version = 2 4391 swift_store_auth_address = http://192.168.100.10:5000/v3 4399 swift_store_user = zlm 4408 swift_store_key = 000000 [root@Controller ~]# systemctl restart openstack-glance-api.service 備考：zlm ユーザーは swiftOperator ロールを付与されて初めて Swift への操作権限を持ちます\n","date":"2026-10-05","description":"","objectID":"/ja/posts/openstack-keystone-glance-nova/","readingTime":5,"tags":["OpenStack","Keystone","Glance","Nova","Endpoint","イメージサービス"],"title":"OpenStack 中核サービス詳細解説：Keystone 認証・Nova コンピュート・Glance/Swift イメージストレージ","url":"/ja/posts/openstack-keystone-glance-nova/","wordCount":1055},{"categories":["OpenStack"],"content":"一、GUI（ダッシュボード）でのクラウドサーバー提供 admin ユーザーはクラウドのスーパー管理者です\nadmin はアイデンティティを管理します\n一、テナント（プロジェクト）の作成\n二、ユーザー作成とプロジェクト紐付け\n三、イメージのアップロード：管理者がアップロードしたイメージはパブリック（全テナントが利用可能）に設定でき、一般ユーザーがアップロードしたイメージはプライベートでテナント内でのみ共有されます。\n四、フレーバーの作成\n五、外部ネットワークの作成\nL3 Agent が配置されたノードがネットワークノードとなります\nテナントとしてログイン\n一、テナント身份でログイン\n二、プライベートネットワークとサブネット（VPC）の作成\n三、ルーター作成と外部ネットワーク・プライベートネットワークの接続\n四、セキュリティグループとルールの作成\n五、キーペアの作成\n六、クラウドサーバー提供と浮動 IP の紐付け\n七、テスト（ログイン・ホスト名・ネットワーク）\ncloud-init がホスト名やパスワードなどのカスタム情報を初期化します\n例えば 20GB のディスクを占有し、快適に動作させるために 4GB のメモリを必要とする大きなイメージを作成したとします。しかしテナントはそれを知らないため、サーバー提供時に 10GB ディスク・2GB メモリのフレーバーを選んで失敗し、原因も分かりません。そこでイメージ登録時に「最小ディスク 20GB・最小メモリ 4GB」を指定しておけば、後にフレーバーを選ぶ際にその条件を満たさないフレーバーは選択できず、条件を満たすものだけを選べるようになります。\n以下は OpenStack Nova において新たに追加されたコンピュートノードを所属する Cell データベースに発見・マッピングするために使う重要なコマンドです。Cells v2 アーキテクチャでは、各コンピュートノードはこの登録ステップを経る必要があり、さもないとスケジューラがその上にインスタンスを配置できず、API にもそのホストが表示されません。\n1 [root@Controller ~(keystone_admin)]# nova-manage cell_v2 discover_hosts --verbose クラウドサーバーはルーター経由でインターネットに出られます。浮动 IP を設定する意味は、外部にサービスを公開することです（Web サーバーは SNAT で外に出られますが、リモートユーザーはそのサービスに入ってこられません）。以下は OpenStack が裏で使っている iptables ルールを確認する方法です。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 [root@Controller ~(keystone_admin)]# ip netns qrouter-aa6470e8-9c0e-4a50-9be6-71566d0c3903 (id: 1) qdhcp-a82a6d9e-26ec-497f-8f71-68d8395386ad (id: 0) [root@Controller ~(keystone_admin)]# ip netns exec qrouter-aa6470e8-9c0e-4a50-9be6-71566d0c3903 ip addr list 1: lo: \u0026lt;LOOPBACK,UP,LOWER_UP\u0026gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 33: qg-d9305000-ef: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether fa:16:3e:18:37:69 brd ff:ff:ff:ff:ff:ff inet 192.168.10.106/24 brd 192.168.10.255 scope global qg-d9305000-ef valid_lft forever preferred_lft forever inet 192.168.10.182/32 brd 192.168.10.182 scope global qg-d9305000-ef valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe18:3769/64 scope link valid_lft forever preferred_lft forever 34: qr-eb02e78e-a3: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether fa:16:3e:18:b8:5f brd ff:ff:ff:ff:ff:ff inet 192.168.20.254/24 brd 192.168.20.255 scope global qr-eb02e78e-a3 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe18:b85f/64 scope link valid_lft forever preferred_lft forever [root@Controller ~(keystone_admin)]# ip netns exec qrouter-aa6470e8-9c0e-4a50-9be6-71566d0c3903 iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination neutron-l3-agent-PREROUTING all -- 0.0.0.0/0 0.0.0.0/0 Chain INPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination neutron-l3-agent-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 neutron-postrouting-bottom all -- 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT) target prot opt source destination neutron-l3-agent-OUTPUT all -- 0.0.0.0/0 0.0.0.0/0 Chain neutron-l3-agent-OUTPUT (1 references) target prot opt source destination DNAT all -- 0.0.0.0/0 192.168.10.182 to:192.168.20.197 Chain neutron-l3-agent-POSTROUTING (1 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ! ctstate DNAT Chain neutron-l3-agent-PREROUTING (1 references) target prot opt source destination REDIRECT tcp -- 0.0.0.0/0 169.254.169.254 tcp dpt:80 redir ports 9697 DNAT all -- 0.0.0.0/0 192.168.10.182 to:192.168.20.197 Chain neutron-l3-agent-float-snat (1 references) target prot opt source destination SNAT all -- 192.168.20.197 0.0.0.0/0 to:192.168.10.182 random-fully Chain neutron-l3-agent-snat (1 references) target prot opt source destination neutron-l3-agent-float-snat all -- 0.0.0.0/0 0.0.0.0/0 SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.10.106 random-fully SNAT all -- 0.0.0.0/0 0.0.0.0/0 mark match ! 0x2/0xffff ctstate DNAT to:192.168.10.106 random-fully Chain neutron-postrouting-bottom (1 references) target prot opt source destination neutron-l3-agent-snat all -- 0.0.0.0/0 0.0.0.0/0 /* Perform source NAT on outgoing traffic. */ 実験課題：インターネットにアクセスできるクラウドサーバーを作成し、yum リポジトリを Alibaba Cloud に向け、httpd パッケージをインストールしてサービスを起動し、外部ホストから Web ページ http://192.168.10.182 にアクセスする。\nCompute ホストは本質的に KVM ハイパーバイザーです。OpenStack がクラウドサーバーを提供する際、スケジューラがいずれかの Compute ホストに分散配置します。\n二、コマンドラインでのクラウドサーバー提供 1 [root@Controller ~(keystone_admin)]# cp keystonerc_admin keystonerc_zlm 要件一：コマンドラインで全リソースを削除\n1 2 3 4 5 6 7 8 9 10 11 12 [root@Controller ~(keystone_zlm)]# cat keystonerc_zlm unset OS_SERVICE_TOKEN export OS_USERNAME=zlm export OS_PASSWORD=\u0026#39;000000\u0026#39; export OS_REGION_NAME=RegionOne export OS_AUTH_URL=http://192.168.100.10:5000/v3 export PS1=\u0026#39;[\\u@\\h \\W(keystone_zlm)]\\$ \u0026#39; export OS_PROJECT_NAME=LMandMY_HOME export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_DOMAIN_NAME=Default export OS_IDENTITY_API_VERSION=3 [root@Controller ~(keystone_zlm)]# source keystonerc_zlm クラウドサーバーの削除 1 2 3 4 5 6 7 [root@Controller ~(keystone_zlm)]# openstack server list +--------------------------------------+------+--------+--------------------------------------+------------------+--------+ | ID | Name | Status | Networks | Image | Flavor | +--------------------------------------+------+--------+--------------------------------------+------------------+--------+ | 44f0fa66-94ed-44ac-a9ae-0a3a13c1faba | web | ACTIVE | VPC01=192.168.20.197, 192.168.10.182 | CentOS 8.4 64bit | m3.web | +--------------------------------------+------+--------+--------------------------------------+------------------+--------+ [root@Controller ~(keystone_zlm)]# openstack server delete 44f0fa66-94ed-44ac-a9ae-0a3a13c1faba ボリュームの削除 1 2 [root@Controller ~(keystone_zlm)]# openstack volume list [root@Controller ~(keystone_zlm)]# openstack volume delete data01 ルーターの削除 1 2 3 4 5 [root@Controller ~(keystone_zlm)]# openstack router list [root@Controller ~(keystone_zlm)]# openstack router show router01 [root@Controller ~(keystone_zlm)]# openstack subnet list [root@Controller ~(keystone_zlm)]# openstack router remove subnet router01 subnet01 [root@Controller ~(keystone_zlm)]# openstack router delete router01 セキュリティグループの削除 1 2 [root@Controller ~(keystone_zlm)]# openstack security group list [root@Controller ~(keystone_zlm)]# openstack security group delete SG01 ネットワークの削除 1 2 [root@Controller ~(keystone_zlm)]# openstack network list [root@Controller ~(keystone_zlm)]# openstack network delete VPC01 admin 身份に切り替えて、パブリックネットワーク・イメージ・フレーバー・テナント・ユーザーなどを削除します。\n1 [root@Controller ~(keystone_zlm)]# source keystonerc_admin パブリックネットワークの削除 1 2 [root@Controller ~(keystone_admin)]# openstack network list [root@Controller ~(keystone_admin)]# openstack network delete public イメージの削除 1 2 3 4 [root@Controller ~(keystone_admin)]# openstack image list [root@Controller ~(keystone_admin)]# openstack image delete e3336d90-e673-4b1b-82ec-69b70fd6402c [root@Controller ~(keystone_admin)]# openstack image delete cec813dd-8141-4a99-8883-805ac6e3ec17 [root@Controller ~(keystone_admin)]# openstack image delete c6ffe7db-ccb0-4df4-8715-e8ce0fd5dc7d フレーバーの削除 1 2 [root@Controller ~(keystone_admin)]# openstack flavor list [root@Controller ~(keystone_admin)]# openstack flavor delete m3.web テナントとユーザーの削除 1 2 3 4 [root@Controller ~(keystone_admin)]# openstack project list [root@Controller ~(keystone_admin)]# openstack project delete LMandMY_HOME [root@Controller ~(keystone_admin)]# openstack user list [root@Controller ~(keystone_admin)]# openstack user delete zlm 要件二：コマンドラインで全リソースを作成—サーバー提供・浮动 IP 追加・サーバーアクセス・ネットワーク作成\n1 [root@Controller ~(keystone_admin)]# source keystonerc_admin プロジェクトとユーザーを作成し紐付け 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@Controller ~(keystone_admin)]# openstack project create LMandMY_HOME [root@Controller ~(keystone_admin)]# openstack user create --project LMandMY_HOME --project-domain Default --password-prompt zlm [root@Controller ~(keystone_admin)]# openstack role list +----------------------------------+------------------+ | ID | Name | +----------------------------------+------------------+ | 0adc17230a5a434195d5995863280b3d | heat_stack_owner | | 2e5abdde67bb4f23bbf15454616af53e | ResellerAdmin | | 46d49fecd6f4411bbd72d0b9f575bcae | admin | | 5f5bf78c40b143bbb2df74fc855ea204 | reader | | 84ebb81407f644b18e1a529e0c317f16 | member | | b83f4c27c83445489554e988fb9af5a1 | heat_stack_user | | b8f8cd45891240bfa0f80e93f0e37ab9 | _member_ | | ebc22a15458c4712bf0dd4f4de09e0bf | SwiftOperator | +----------------------------------+------------------+ [root@Controller ~(keystone_admin)]# openstack role add --user zlm --project LMandMY_HOME b8f8cd45891240bfa0f80e93f0e37ab9 イメージのアップロード 1 [root@Controller ~(keystone_admin)]# openstack image create --file /data/cirros-0.3.5-x86_64-disk.img --disk-format qcow2 --container-format bare --public cirros フレーバーの作成 1 [root@Controller ~(keystone_admin)]# openstack flavor create --ram 1024 --disk 10 --public m3.web パブリックネットワークとサブネットの作成 1 [root@Controller ~(keystone_admin)]# openstack network create --external --share --provider-network-type flat --provider-physical-network extnet --project LMandMY_HOME public サブネットの作成\n1 [root@Controller ~(keystone_admin)]# openstack subnet create --no-dhcp --subnet-range 192.168.10.0/24 --allocation-pool start=192.168.10.100,end=192.168.10.200 --gateway 192.168.10.1 --network public publicsub01 テナント身份に切り替え\n1 [root@Controller ~(keystone_admin)]# source keystonerc_zlm ネットワークとサブネットの作成 1 [root@Controller ~(keystone_zlm)]# openstack network create VPC01 サブネットの作成\n1 [root@Controller ~(keystone_zlm)]# openstack subnet create --network VPC01 --subnet-range 192.168.20.0/24 --dhcp --gateway 192.168.20.254 --dns-nameserver 114.114.114.114 subnet01 ルーターの作成 1 2 3 [root@Controller ~(keystone_zlm)]# openstack router create router01 [root@Controller ~(keystone_zlm)]# openstack router add subnet router01 subnet01 [root@Controller ~(keystone_zlm)]# openstack router set --external-gateway public router01 セキュリティグループの作成 1 [root@Controller ~(keystone_zlm)]# openstack security group create SG01 ICMP プロトコルを許可\n1 [root@Controller ~(keystone_zlm)]# openstack security group rule create --ingress --protocol icmp --remote-ip 0.0.0.0/0 SG01 SSH サービスを許可\n1 [root@Controller ~(keystone_zlm)]# openstack security group rule create --ingress --protocol tcp --dst-port 22 --remote-ip 0.0.0.0/0 SG01 ポート 80 を許可\n1 [root@Controller ~(keystone_zlm)]# openstack security group rule create --ingress --protocol tcp --dst-port 80 --remote-ip 0.0.0.0/0 SG01 フローティング IP の作成 1 [root@Controller ~(keystone_zlm)]# openstack floating ip create public キーペアの作成 1 [root@Controller ~(keystone_zlm)]# openstack key create key01 \u0026gt; key01.pem クラウドサーバーの作成 1 2 3 4 5 6 7 8 [root@Controller ~(keystone_zlm)]# openstack network list +--------------------------------------+--------+--------------------------------------+ | ID | Name | Subnets | +--------------------------------------+--------+--------------------------------------+ | a82a6d9e-26ec-497f-8f71-68d8395386ad | VPC01 | 40bd75e0-3d22-4e7b-8659-8a6c0a44e3aa | | d99ba601-05e3-4f1f-88b8-f0587c6a5f6e | public | 5d39db23-8359-4e33-bde7-0f9ac6a0f7c7 | +--------------------------------------+--------+--------------------------------------+ [root@Controller ~(keystone_zlm)]# openstack server create --image cirros --security-group SG01 --key-name key01 --flavor m3.web --nic net-id=a82a6d9e-26ec-497f-8f71-68d8395386ad web 浮动 IP をクラウドサーバーに紐付け\n1 2 [root@Controller ~(keystone_zlm)]# openstack port list [root@Controller ~(keystone_zlm)]# openstack floating ip set --port=46ba21d5-6f14-4693-a215-5a6fc8781adf 192.168.10.182 クラウドサーバーへのアクセス\n1 2 [root@Controller ~(keystone_zlm)]# chmod 400 key01.pem [root@Controller ~(keystone_zlm)]# ssh -i key01.pem cirros@192.168.10.182 外部ネットワークの NIC が通信できない場合\n1 [root@Controller ~(keystone_zlm)]# ifup br-ex ; ifup ens224 ","date":"2026-10-04","description":"","objectID":"/ja/posts/openstack-provision-cloud-server/","readingTime":6,"tags":["OpenStack","クラウドサーバー","Horizon","Neutron","Nova","CLI"],"title":"OpenStack でのクラウドサーバー提供","url":"/ja/posts/openstack-provision-cloud-server/","wordCount":1150},{"categories":["MySQL"],"content":"01 - systemctl データベース Service ファイルの整理 方案1：標準本番デーモン設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [Unit] Description=MySQL Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid ExecReload=/bin/kill -HUP $MAINPID PIDFile=/var/run/mysqld/mysqld.pid PrivateTmp=true RuntimeDirectory=mysqld [Install] WantedBy=multi-user.target 方案2：設定ファイルとファイルハンドル制限付き 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [Unit] Description=MySQL Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf RuntimeDirectory=mysqld LimitNOFILE=65536 Restart=on-failure [Install] WantedBy=multi-user.target 修正完了後\n1 2 3 [root@master local]#systemctl daemon-reload [root@master local]#systemctl restart mysqld.service [root@master local]#systemctl enable mysqld.service 02 - マルチバージョン MySQL（5.6 / 5.7）インストールとアップグレード準備実戦 手順1：ソフトウェアアーカイブのダウンロード 1 2 3 4 5 # MySQL 5.7.40 バイナリパッケージ [root@master local]#wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.40-linux-glibc2.12-x86_64.tar.gz # MySQL 5.6.48 バイナリパッケージ [root@master local]#wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.48-linux-glibc2.12-x86_64.tar.gz 手順2：展開・インストールとシンボリックリンク作成 1 2 3 4 5 6 7 8 9 # 5.7 のインストール [root@master local]#tar xf mysql-5.7.40-linux-glibc2.12-x86_64.tar.gz [root@master local]#ln -s mysql-5.7.40-linux-glibc2.12-x86_64 mysql57 # 注意：マルチバージョン共存デバッグ中はグローバル環境変数を設定せず、コマンドパスの衝突を回避 # 5.6 のインストール [root@master local]#tar xf mysql-5.6.48-linux-glibc2.12-x86_64.tar.gz [root@master local]#ln -s mysql-5.6.48-linux-glibc2.12-x86_64 mysql56 # 注意：今のところグローバル環境変数は設定しない 手順3：データベースソフトウェアの初期化 MySQL 5.7 初期化（データディレクトリ 3357）:\n1 2 3 4 5 [root@master local]#mkdir -p /data/3357/data [root@master local]#chown -R mysql.mysql /data/3357/data [root@master local]#/usr/local/mysql57/bin/mysqld --initialize-insecure --user=mysql --datadir=/data/3357/data --basedir=/usr/local/mysql57 [root@master local]#echo $? 0 MySQL 5.6 初期化（データディレクトリ 3356）:\n1 2 3 4 5 6 7 8 9 10 11 [root@master local]#mkdir -p /data/3356/data [root@master local]#chown -R mysql.mysql /data/3356/data [root@master local]#/usr/local/mysql56/scripts/mysql_install_db --user=mysql --datadir=/data/3356/data --basedir=/usr/local/mysql56 FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql56/scripts/mysql_install_db: Data::Dumper # Perl モジュール不足 [root@master local]#yum install -y perl-Data-Dumper [root@master local]#/usr/local/mysql56/scripts/mysql_install_db --user=mysql --datadir=/data/3356/data --basedir=/usr/local/mysql56 # 出力に 2 つの OK が含まれるか確認し、終了コードを確認： [root@master local]#echo $? 0 手順4：マルチインスタンス専用設定ファイルの作成 MySQL 5.7（インスタンス 3357）設定:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@master local]#vim /etc/my3357.cnf [mysql] socket=/tmp/mysql3357.sock [mysqld] user=mysql basedir=/usr/local/mysql57 datadir=/data/3357/data socket=/tmp/mysql3357.sock port=3357 pid-file=/run/mysqld3357/mysqld.pid [root@master local]#vim /usr/lib/systemd/system/mysqld3357.service [Unit] Description=MySQL 5.7 Server (3357) After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql57/bin/mysqld --defaults-file=/etc/my3357.cnf RuntimeDirectory=mysqld3357 LimitNOFILE=65536 Restart=on-failure [Install] WantedBy=multi-user.target MySQL 5.6（インスタンス 3356）設定:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@master local]#vim /etc/my3356.cnf [mysql] socket=/tmp/mysql3356.sock [mysqld] user=mysql basedir=/usr/local/mysql56 datadir=/data/3356/data socket=/tmp/mysql3356.sock port=3356 pid-file=/run/mysqld3356/mysqld.pid [root@master local]#vim /usr/lib/systemd/system/mysqld3356.service [Unit] Description=MySQL 5.6 Server (3356) After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql56/bin/mysqld --defaults-file=/etc/my3356.cnf RuntimeDirectory=mysqld3356 LimitNOFILE=65536 Restart=on-failure [Install] WantedBy=multi-user.target 手順5：起動・管理の実行検証 MySQL 5.7 サービスの起動/停止:\n1 2 3 4 5 6 7 8 9 10 11 # 方式1：起動 [root@master local]#cp /usr/local/mysql57/support-files/mysql.server /etc/init.d/mysqld57 [root@master local]#chmod +x /etc/init.d/mysqld57 [root@master local]#/etc/init.d/mysqld57 start [root@master local]#/etc/init.d/mysqld57 stop # 方式2：起動 [root@master local]#systemctl daemon-reload [root@master local]#systemctl start mysqld3357.service [root@master local]#systemctl enable mysqld3357.service Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld3357.service to /usr/lib/systemd/system/mysqld3357.service. MySQL 5.6 サービスの起動/停止:\n1 2 3 4 5 6 7 8 9 10 11 # 方式1：起動 [root@master local]#cp /usr/local/mysql56/support-files/mysql.server /etc/init.d/mysqld56 [root@master local]#chmod +x /etc/init.d/mysqld56 [root@master local]#/etc/init.d/mysqld56 start [root@master local]#/etc/init.d/mysqld56 stop # 方式2：起動 [root@master local]#systemctl daemon-reload [root@master local]#systemctl start mysqld3356.service [root@master local]#systemctl enable mysqld3356.service Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld3356.service to /usr/lib/systemd/system/mysqld3356.service. 3 つのサービスの状態確認（すべて running）\n1 2 3 4 5 6 7 8 [root@master local]#for svc in mysqld mysqld3356 mysqld3357; do \u0026gt; a=$(systemctl show -p ActiveState \u0026#34;$svc\u0026#34; | cut -d= -f2) \u0026gt; s=$(systemctl show -p SubState \u0026#34;$svc\u0026#34; | cut -d= -f2) \u0026gt; echo \u0026#34;$svc: $a ($s)\u0026#34; \u0026gt; done mysqld: active (running) mysqld3356: active (running) mysqld3357: active (running) ","date":"2026-10-03","description":"","objectID":"/ja/posts/systemd-mysql-multiversion/","readingTime":3,"tags":["MySQL","systemd","マルチバージョン導入"],"title":"systemd サービス管理と MySQL マルチバージョン導入","url":"/ja/posts/systemd-mysql-multiversion/","wordCount":518},{"categories":["MySQL"],"content":"01 - データベースサービスのインストールとデプロイ 1.1 データベースサーバーパッケージのダウンロード 公式ダウンロード先（過去のアーカイブバイナリパッケージ）：\n1 2 3 # 格納ディレクトリ [root@master ~]#cd /usr/local/ [root@master local]#wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz パッケージ情報を確認\n1 2 [root@master local]#ll mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz -rw-r--r-- 1 root root 914806904 Jul 2 2021 mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz 1.2 バイナリパッケージからのデータベースサーバーインストール 手順1：OS 環境の準備 1. ネットワークアドレスの確認 1 2 3 4 5 6 7 [root@master local]#ip addr show eth0 2: eth0: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:4b:b7:38 brd ff:ff:ff:ff:ff:ff inet 11.0.1.101/24 brd 11.0.1.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe4b:b738/64 scope link valid_lft forever preferred_lft forever 2. ホスト名解決の設定 1 2 3 4 [root@master local]#vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 11.0.1.101 master 3. システムファイアウォールを無効化 1 [root@master local]#systemctl disable firewalld --now 4. SELinux を無効化 1 2 3 4 5 [root@master local]#sed -i \u0026#39;s/^SELINUX=enforcing/SELINUX=disabled/\u0026#39; /etc/selinux/config # 再起動で反映 [root@master local]#reboot [root@master local]#getenforce Disabled 5. データベースインストール時の競合を回避 1 2 3 4 5 6 # システムに標準搭載の mariadb が存在するか確認 [root@master local]#rpm -qa | grep mariadb mariadb-libs-5.5.68-1.el7.x86_64 # システム標準のデータベースパッケージをアンインストール [root@master local]#yum remove -y mariadb-libs 6. データベース依存ソフトをインストール（欠けると初期化エラー） 1 [root@master local]#yum install -y libaio-devel 手順2：データベースソフトウェアのインストール 1. パッケージを展開しシンボリックリンクを作成（バージョン管理用） 1 2 [root@master local]#tar xf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz [root@master local]#ln -s mysql-8.0.26-linux-glibc2.12-x86_64 mysql 2. システム全体の環境変数を設定 1 2 3 4 5 [root@master local]#vim /etc/profile # ファイル末尾に追加 export PATH=$PATH:/usr/local/mysql/bin # 設定を反映 [root@master local]#source /etc/profile 3. インストールバージョンを確認 1 2 [root@master local]#mysql -V mysql Ver 8.0.26 for Linux on x86_64 (MySQL Community Server - GPL) 手順3：ソフトウェアの初期化 MySQL には2つのコアディレクトリがある：\nプログラムディレクトリ: /usr/local/mysql データディレクトリ: /data/3306/data（実際のデータを格納） 1. 専用実行ユーザーを作成（システムログイン不要） 1 [root@master local]#useradd mysql -M -s /sbin/nologin 2. データディレクトリを作成し権限を設定 1 2 [root@master local]#mkdir /data/3306/data -p [root@master local]#chown mysql.mysql /data/3306/data 3. データディレクトリを初期化 1 2 3 4 5 # 存在する可能性のある干渉設定ファイルを削除 [root@master local]#rm -f /etc/my.cnf # パスワードなし初期化を実行（初期化後管理者はパスワードなし） [root@master local]#mysqld --initialize-insecure --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql 手順4：データベースサービス設定ファイルの作成 /etc/my.cnf を作成・編集：\n1 2 3 4 5 6 7 8 9 10 [root@master local]#cat \u0026gt; /etc/my.cnf \u0026lt;\u0026lt; \u0026#39;eof\u0026#39; \u0026gt; [mysql] \u0026gt; socket=/tmp/mysql.sock \u0026gt; \u0026gt; [mysqld] \u0026gt; user=mysql \u0026gt; basedir=/usr/local/mysql \u0026gt; datadir=/data/3306/data \u0026gt; socket=/tmp/mysql.sock \u0026gt; eof 注: 設定ファイル内の basedir と datadir のパスは実際の環境に合わせて調整する。\n手順5：データベースサービスの起動 1. 公式サービス管理スクリプトで起動 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@master local]#cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld [root@master local]#/etc/init.d/mysqld start Starting MySQL.Logging to \u0026#39;/data/3306/data/master.err\u0026#39;. . SUCCESS! # 正常にデータベースに入れれば起動成功 [root@master local]#mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 8 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; 2. コマンドラインから直接起動 mysqld コマンドで起動: 1 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql --socket=/tmp/mysql.sock \u0026amp; mysqld_safe セーフデーモンで起動: 1 /usr/local/mysql/bin/mysqld_safe --datadir=/data/3306/data \u0026amp; 3. systemctl / service で起動 方法1: 専用の Systemd Unit ファイルを作成 (/etc/systemd/system/mysqld.service) 方法2: /etc/init.d/ 配下のサービススクリプトを直接有効化・呼び出し： 1 2 3 4 systemctl enable mysqld service mysqld start # または systemctl start mysqld 1.3 補足知識 1. 初期化の2つの方法の比較 方法1：非セキュア初期化 (--initialize-insecure)\n1 mysqld --initialize-insecure --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql 特徴: データベース管理者にパスワードがなく、そのままパスワードなしでログインでき、テストやスクリプト初期化に便利。 方法2：セキュア初期化 (--initialize)\n1 mysqld --initialize --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql 特徴: データベース管理者にランダムな一時パスワードが生成され、ログに出力され、初回ログインに使用する。 注意: 一時パスワードは初回ログイン専用。ログイン後は必ず新しいパスワードを再設定する必要があり、変更前は他の操作を実行できない： 1 ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; 2. 起動失敗の標準トラブルシューティング手順 手順1：システム基本環境の確認 SELinux が完全に無効化されているか確認； ポート 3306 が占有されていないか、他の競合するデータベースサービスプロセスが存在しないか確認。 手順2：エラーログの調査と分析 典型的なエラー: Starting MySQL. ERROR! ... PID file ... エラーログの詳細を確認： 1 2 3 cat /data/3306/data/master.err # ログエラー例: # 2024-06-14T09:15:36.120048Z 1 [ERROR] [MY-012271] [InnoDB] The innodb_system data file \u0026#39;ibdata1\u0026#39; must be writable 手順3：エラーログがない場合の調査方法 設定ファイル /etc/my.cnf を確認： 設定ファイルのパスとファイル名が正しいか確認； 設定ファイル内のパラメータ構文とパス設定が正しいか確認。 02 - データベースサービスの起動と停止 データベースサービスを起動・停止する方法は複数あり、一般的なものを以下にまとめる：\n番号 起動方法 対応する停止方法 説明と推奨 01 mysqld \u0026amp; kill / pkill / killall 非推奨；kill -9 の使用は厳禁 02 mysqld_safe \u0026amp; kill / pkill / killall 直接 kill は非推奨 03 mysql.server start mysql.server stop 公式ネイティブ制御スクリプト 04 service mysqld start service mysqld stop 推奨（古典的サービス管理） 05 systemctl start mysqld systemctl stop mysqld 推奨（現代 Linux 標準） 06 クライアント/管理コマンド mysqladmin -uroot -pパスワード shutdown 管理者がリモート/ローカル命令行から優雅に停止 07 SQL セッション内での停止 端末で shutdown; を実行 管理者権限が必要 03 - データベースサービスのパスワード管理 1. パスワードがない場合の設定 方法1：コマンドライン操作\n1 2 3 [root@master local]#mysqladmin -uroot password \u0026#39;123456\u0026#39; mysqladmin: [Warning] Using a password on the command line interface can be insecure. Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety. 方法2：SQL 文の操作\n1 2 mysql\u0026gt; ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;000000\u0026#39;; Query OK, 0 rows affected (0.02 sec) 2. 既存パスワードの変更 方法1：コマンドライン操作 1 2 3 [root@master local]#mysqladmin -uroot -p000000 password \u0026#39;123456\u0026#39; mysqladmin: [Warning] Using a password on the command line interface can be insecure. Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety. 方法2：SQL 文の操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@master local]#mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 14 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; Query OK, 0 rows affected (0.00 sec) mysql\u0026gt; 3. パスワードを忘れた場合（リセット） パスワードリセットの実践手順 手順1：データベースサービスを停止\n1 mysql\u0026gt; shutdown; またはシステム端末で実行：\n1 2 3 4 [root@master local]#service mysqld stop Shutting down MySQL.. SUCCESS! # または pkill mysqld 手順2：セーフモードで起動（権限テーブル読み込みをスキップし、パスワードなしログインを実現）\n1 2 [root@master local]#/usr/local/mysql/bin/mysqld_safe --datadir=/data/3306/data --skip-grant-tables --skip-networking \u0026amp; [1] 2658 説明: --skip-networking はネットワークリスニングを無効にし、パスワードなし期間中に他のネットワーククライアントが介入するのを防ぐ。\n手順3：パスワードなしでログインし、リセット\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@master local]#mysql Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 7 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec) mysql\u0026gt; ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; Query OK, 0 rows affected (0.00 sec) mysql\u0026gt; MySQL ターミナルで順に実行：\n1 2 3 4 5 6 7 -- 1. 権限テーブルをフラッシュ（メモリとディスクの権限テーブルを同期） -- 作用1：メモリ上の権限テーブル情報をディスクに同期書き込み -- 作用2：ディスク上の権限テーブル情報をメモリに再読み込み FLUSH PRIVILEGES; -- 2. パスワードをリセット ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; 注意: FLUSH PRIVILEGES; を実行せずに ALTER USER を直接実行すると、システムがエラーをスローする：\n1 ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 手順4：データベースサービスを正常に再起動\n1 2 3 4 5 6 7 # 一時セーフモードプロセスを終了 [root@master local]#pkill mysqld # データベースサービスを正常に起動 [root@master local]#/etc/init.d/mysqld start Starting MySQL.. SUCCESS! # または service mysqld start 手順5：新しいパスワードでログイン検証\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@master local]#mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 8 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; ","date":"2026-10-03","description":"","objectID":"/ja/posts/mysql-binary-deploy/","readingTime":6,"tags":["MySQL","データベース","バイナリインストール"],"title":"MySQL 実践：バイナリインストール・起動停止・パスワード管理","url":"/ja/posts/mysql-binary-deploy/","wordCount":1170},{"categories":["DevOps"],"content":"01. SonarQube 概要 1 2 3 1. SonarQube は Java で開発されており、Open JDK 8 が必要 2. SonarQube は MySQL データベースに依存し、少なくとも 5.6 以上 3. SonarQube の小規模インスタンスは最低 4G、大規模インスタンスは 16G のメモリが必要 02. デプロイ 1. JDK 実行環境をインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@sonarqube ~]#ll total 166040 -rw-r--r-- 1 root root 170023183 Oct 1 22:32 jdk-8u181-linux-x64.rpm [root@sonarqube ~]#rpm -ivh jdk-8u181-linux-x64.rpm warning: jdk-8u181-linux-x64.rpm: Header V3 RSA/SHA256 Signature, key ID ec551f03: NOKEY Preparing... ################################# [100%] Updating / installing... 1:jdk1.8-2000:1.8.0_181-fcs ################################# [100%] Unpacking JAR files... tools.jar... plugin.jar... javaws.jar... deploy.jar... rt.jar... jsse.jar... charsets.jar... localedata.jar... 2. データベースをインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # 1. MySQL 公式 Yum リポジトリ設定ファイルをダウンロード [root@sonarqube ~]#wget dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm # 2. MySQL リポジトリをインストール [root@sonarqube ~]#rpm -ivh mysql-community-release-el6-5.noarch.rpm Preparing... ################################# [100%] Updating / installing... 1:mysql-community-release-el6-5 ################################# [100%] # 3. MySQL サーバーをインストール [root@sonarqube ~]# yum install mysql-community-server -y [root@sonarqube ~]#mysql --version mysql Ver 14.14 Distrib 5.6.51, for Linux (x86_64) using EditLine wrapper # 4. MySQL サービスを起動 [root@sonarqube ~]#service mysqld start Starting mysqld (via systemctl): [ OK ] [root@sonarqube ~]#netstat -ntpl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1227/master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1008/sshd tcp6 0 0 ::1:25 :::* LISTEN 1227/master tcp6 0 0 :::3306 :::* LISTEN 3113/mysqld tcp6 0 0 :::22 :::* LISTEN 1008/sshd # 5. パスワードを設定 [root@sonarqube ~]# mysqladmin -uroot password 000000 # 6. sonarqube データベースを作成 [root@sonarqube ~]# mysql -uroot -p000000 -e \u0026#34;CREATE DATABASE sonarqube DEFAULT CHARACTER SET utf8;\u0026#34; [root@sonarqube ~]#mysql -u root -p000000 -e \u0026#34;show databases\u0026#34; Warning: Using a password on the command line interface can be insecure. +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sonarqube | +--------------------+ 3. SonarQube をインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 # 1. SonarQube パッケージをアップロード [root@sonarqube ~]# cd /usr/local/ [root@sonarqube local]#ll sonarqube-7.0.zip -rw-r--r-- 1 root root 155709573 Oct 1 22:50 sonarqube-7.0.zip # 2. 現在のディレクトリに展開 [root@sonarqube local]#yum install -y unzip [root@sonarqube local]# unzip sonarqube-7.0.zip [root@sonarqube local]# ln -s sonarqube-7.0 sonarqube # 3. プラグインをインストール: 既定のプラグインを削除: [root@sonarqube ~]# rm -rf /usr/local/sonarqube/extensions/plugins/* プラグインをアップロード: [root@sonarqube ~]#ll sonar_plugins.tar.gz -rw-r--r-- 1 root root 45106788 Oct 1 22:56 sonar_plugins.tar.gz [root@sonarqube ~]#tar xf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions/plugins/ [root@sonarqube ~]#ll /usr/local/sonarqube/extensions/plugins/ total 4 drwxr-xr-x 2 1000 1000 4096 Oct 24 2019 plugins [root@sonarqube ~]# cd /usr/local/sonarqube/extensions/plugins/ [root@sonarqube plugins]# mv plugins/* . [root@sonarqube plugins]#rm -fr plugins/ # 4. 一般ユーザーを作成 [root@sonarqube ~]# useradd sonarqube # 5. コードの所有者を sonarqube に変更 [root@sonarqube ~]# chown -R sonarqube.sonarqube /usr/local/sonarqube/ [root@sonarqube ~]# ll /usr/local/sonarqube/ total 12 drwxr-xr-x 8 sonarqube sonarqube 136 Feb 2 2018 bin drwxr-xr-x 2 sonarqube sonarqube 50 May 15 15:09 conf -rw-r--r-- 1 sonarqube sonarqube 7651 Feb 2 2018 COPYING drwxr-xr-x 2 sonarqube sonarqube 24 Feb 2 2018 data drwxr-xr-x 7 sonarqube sonarqube 150 Feb 2 2018 elasticsearch drwxr-xr-x 4 sonarqube sonarqube 40 Feb 2 2018 extensions drwxr-xr-x 9 sonarqube sonarqube 138 Feb 2 2018 lib drwxr-xr-x 2 sonarqube sonarqube 6 Feb 2 2018 logs drwxr-xr-x 2 sonarqube sonarqube 24 Feb 2 2018 temp drwxr-xr-x 9 sonarqube sonarqube 4096 Feb 2 2018 web # 6. データベース接続を設定 [root@sonarqube ~]#vim /usr/local/sonarqube/conf/sonar.properties ... sonar.jdbc.username=root # データベースユーザー名 sonar.jdbc.password=000000 # データベースパスワード #----- Embedded Database (default) # H2 embedded database server listening port, defaults to 9092 #sonarqube.embeddedDatabase.port=9092 #----- MySQL 5.6 or greater # Only InnoDB storage engine is supported (not myISAM). # Only the bundled driver is supported. It can not be changed. sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarqube?useUnicode=true\u0026amp;characterE ncoding=utf8\u0026amp;rewriteBatchedStatements=true\u0026amp;useConfigs=maxPerformance\u0026amp;useSSL =false # ローカル接続を有効化 ... 4. SonarQube を起動 1 2 SonarQube は root では起動できず、一般ユーザーで実行する必要がある [root@sonarqube ~]# su - sonarqube -c \u0026#34;/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start\u0026#34; 5. リモートアクセストークンを設定 起動後はポート 9000 で、ブラウザで http://11.0.1.202:9000/about を開き、admin / admin でログインし、トークンを生成する（一度しか表示されないので控えておく）。\n1 2 3 4 5 [root@jenkins ~]# sonar-scanner \\ -Dsonar.projectKey=html \\ -Dsonar.sources=. \\ -Dsonar.host.url=http://11.0.1.202:9000 \\ -Dsonar.login=a3bd8e829343edabbbc58fefe0d3e97fdb12268b 6. クライアントのデプロイ クライアントIP: 11.0.1.201\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # 1. クライアントをアップロード [root@jenkins ~]# cd /usr/local/ [root@jenkins ~]#ll sonar-scanner-cli-4.2.0.1873-linux.zip -rw-r--r-- 1 root root 42397119 Oct 2 00:09 sonar-scanner-cli-4.2.0.1873-linux.zip # 2. 展開してシンボリックリンクを作成 [root@jenkins local]#yum install -y unzip [root@jenkins local]#unzip /root/sonar-scanner-cli-4.2.0.1873-linux.zip [root@jenkins local]# ln -s sonar-scanner-4.2.0.1873-linux sonar # 3. グローバル PATH 変数を設定 [root@jenkins ~]# export PATH=\u0026#34;$PATH:/usr/local/sonar/bin/\u0026#34; # 4. 変数を /etc/profile に永続化 [root@jenkins ~]# vim /etc/profile .. export PATH=\u0026#34;$PATH:/usr/local/sonar/bin/\u0026#34; # 5. クライアントからサーバーにコードをスキャンして解析テスト /var/lib/jenkins/workspace/test_job/ 配下の blog コードを SonarQube にプッシュしてテスト [root@jenkins ~]#cd /var/lib/jenkins/workspace/test_job/ [root@jenkins test_job]#ll total 8 -rw-r--r-- 1 root root 7 Oct 1 20:32 a.txt -rw-r--r-- 1 root root 3634 Oct 1 20:32 blog_state.txt -rw-r--r-- 1 root root 0 Oct 1 21:12 c.txt drwxr-xr-x 2 root root 6 Oct 1 20:32 myblog drwxr-xr-x 2 root root 6 Oct 1 20:32 myblog-deploy [root@jenkins test_job]#sonar-scanner \\ -Dsonar.projectKey=html \\ -Dsonar.sources=. \\ -Dsonar.host.url=http://11.0.1.202:9000 \\ -Dsonar.login=a3bd8e829343edabbbc58fefe0d3e97fdb12268b 実行成功:\nサーバーを確認: アップロード成功\n","date":"2026-10-02","description":"","objectID":"/ja/posts/sonarqube-practice/","readingTime":5,"tags":["DevOps","SonarQube","CI/CD"],"title":"SonarQube 実践：プライベート導入・トークン設定・コード品質スキャン","url":"/ja/posts/sonarqube-practice/","wordCount":865},{"categories":["DevOps"],"content":"01. Jenkins 概要 公式サイト：jenkins.io\nJenkins はオープンソースのプロジェクトで、Java ベースの継続的インテグレーション（CI）ツールである。繰り返しの作業を監視し、オープンで使いやすいソフトウェアプラットフォームを提供し、ソフトウェアの CI を可能にする。\n02. Jenkins のデプロイ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 I. 環境準備 1、OS：CentOS 7.9 2、メモリ：実験用 2G、本番用 6G 以上 3、ファイアウォールを無効化し、SELinux を無効にする 4、JDK17 II. JDK をインストール RPM パッケージをアップロード [root@jenkins ~]#ll total 178212 -rw-r--r-- 1 root root 182486159 Oct 1 19:04 jdk-17_linux-x64_bin.rpm [root@jenkins ~]#rpm -ivh jdk-17_linux-x64_bin.rpm warning: jdk-17_linux-x64_bin.rpm: Header V3 RSA/SHA256 Signature, key ID ad986da3: NOKEY Preparing... ################################# [100%] Updating / installing... 1:jdk-17-2000:17.0.11-7 ################################# [100%] インストールが成功したか確認： [root@jenkins ~]# rpm -qa|grep jdk jdk-17-17.0.11-7.x86_64 II. Jenkins をインストール Jenkins パッケージをアップロード [root@jenkins ~]#ll total 269432 -rw-r--r-- 1 root root 182486159 Oct 1 19:04 jdk-17_linux-x64_bin.rpm -rw-r--r-- 1 root root 93405530 Oct 1 19:06 jenkins-2.405-1.1.noarch.rpm [root@jenkins ~]#rpm -ivh jenkins-2.405-1.1.noarch.rpm warning: jenkins-2.405-1.1.noarch.rpm: Header V4 RSA/SHA512 Signature, key ID ef5975ca: NOKEY Preparing... ################################# [100%] Updating / installing... 1:jenkins-2.405-1.1 ################################# [100%] III. Jenkins の実行ユーザーを root に変更 1) 設定ファイルの実行ユーザーを変更 [root@jenkins ~]# vim /etc/sysconfig/jenkins ... JENKINS_USER=\u0026#34;root\u0026#34; ... 2) 起動設定のユーザーを変更 [root@jenkins ~]# vim /usr/lib/systemd/system/jenkins.service ... User=root Group=root ... [root@jenkins ~]# systemctl daemon-reload 3) フォント設定をインストール [root@jenkins ~]# yum -y install fontconfig IV. Jenkins を起動し、起動時に有効化 [root@jenkins ~]# systemctl start jenkins [root@jenkins ~]# systemctl enable jenkins 03. Jenkins へログイン 04. パスワードを変更 パスワード変更後は再ログイン（ユーザー名は admin）\n05. プラグインのインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1. プラグインを Jenkins のホームディレクトリにアップロード [root@jenkins ~]# cd /var/lib/jenkins/ [root@jenkins ~]#ll total 576228 -rw-r--r-- 1 root root 182486159 Oct 1 19:04 jdk-17_linux-x64_bin.rpm -rw-r--r-- 1 root root 93405530 Oct 1 19:06 jenkins-2.405-1.1.noarch.rpm -rw-r--r-- 1 root root 314156543 Oct 1 19:30 jenkins_plu.tar.gz 2. プラグインを plugins ディレクトリに展開 [root@jenkins jenkins]#tar xf /root/jenkins_plu.tar.gz -C plugins/ 3. Jenkins を再起動して反映 [root@jenkins ~]# systemctl restart jenkins 06. プロジェクトを作成 フリープロジェクトを作成し、pwd を実行して Jenkins が使用する既定の作業ディレクトリを確認\n補足：Jenkins がプロジェクトを作成すると、ホーム /var/lib/jenkins/ 配下に workspace ディレクトリを自動作成し、その中にプロジェクト名のディレクトリを作成する。\n以降、Jenkins が GitLab からプルしたコードはこのプロジェクトディレクトリ配下に格納される。\n1 2 [root@jenkins ~]#ls /var/lib/jenkins/workspace/ test_job GitLab と Jenkins を連携させる\n連携前は接続できない旨が表示される：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 鍵認証（非対話）を設定 [root@jenkins ~]#ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory \u0026#39;/root/.ssh\u0026#39;. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:Rr4ouinx/cPqVxJsxju2Cjd1mhWmWSuKGOKG532uTvk root@jenkins The key\u0026#39;s randomart image is: +---[RSA 2048]----+ | | | | | o = | | *B o | |o o=oS | |=o . +=O.. | |o=+.Bo+=. | |oo.B.+* | | .=+BOE. | +----[SHA256]-----+ [root@jenkins ~]#cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+kaj/NEwHKaIErMEClVYuG3JuWr9CD7XpuO5YZ6JftMmNdAPMrvS0mWqP4SDyT6/le0j1RGkA48GsirESfMqXKvzSSd5AuhIPmUADtGPNK6VSeiMKyoWgiNBFLn6RIOAcXI0MuZrYQMLJz+kOYr6kF9em/6MfFQrLkt9DzIlnR9b7CMLyDnPOZ8FG640DqqX0sZ8G+i2v41VX/c7RGIWAgEhJY+kiMS5cDxWlTf2k8hoZmh0VIa/G9AwnvbklyUiE4ACd9GtEJG5xXJzedn7q0/Ygfr26T29t+KST3SlyrXIaEbEC5WwIMymCEJDCPPCGzqLjsWa+4dbJhoEM1afV root@jenkins # Jenkins に git をインストール [root@jenkins ~]#yum install -y git GitLab に Jenkins が生成した鍵を追加：\nJenkins 上で一度 git clone し、初回の yes 入力を完了させる\n1 2 3 4 5 6 7 8 9 10 11 12 13 [root@jenkins ~]#git clone git@11.0.1.200:dawn/blog.git Cloning into \u0026#39;blog\u0026#39;... The authenticity of host \u0026#39;11.0.1.200 (11.0.1.200)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:Ldn1vBzBEFxynXs0qBNr0XzJ2lTx/0caMuK5yJtb+Zo. ECDSA key fingerprint is MD5:3d:1d:28:3f:33:ec:ee:c1:69:83:af:14:a3:7f:79:ac. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;11.0.1.200\u0026#39; (ECDSA) to the list of known hosts. remote: Enumerating objects: 20, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (8/8), done. remote: Total 20 (delta 0), reused 0 (delta 0), pack-reused 11 Receiving objects: 100% (20/20), done. Resolving deltas: 100% (2/2), done. これで接続できるようになる\n再度ビルドしてプルをテスト\nプル成功\nWebhook を設定\nWebhook を設定し、GitLab のコードを Jenkins が自動的にプルしてビルドするよう構成\n両方保存してテスト\nプロジェクトを修正して再度プッシュしてテスト\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [root@gitlab blog]#git branch * master [root@gitlab blog]#touch c.txt [root@gitlab blog]#git add . [root@gitlab blog]#git commit -m \u0026#34;test_v2\u0026#34; [master 7b1f29e] test_v2 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 c.txt [root@gitlab blog]#git pull origin master remote: Enumerating objects: 17, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (8/8), done. remote: Total 17 (delta 0), reused 0 (delta 0), pack-reused 8 Unpacking objects: 100% (17/17), done. From 11.0.1.200:dawn/blog * branch master -\u0026gt; FETCH_HEAD Merge made by the \u0026#39;recursive\u0026#39; strategy. a.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 a.txt [root@gitlab blog]#git push -u origin master Counting objects: 7, done. Delta compression using up to 2 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 469 bytes | 0 bytes/s, done. Total 5 (delta 2), reused 0 (delta 0) To git@11.0.1.200:dawn/blog.git 47f606c..91e80a5 master -\u0026gt; master Branch master set up to track remote branch master from origin. 自動ビルド成功\n","date":"2026-10-01","description":"","objectID":"/ja/posts/jenkins-practice/","readingTime":4,"tags":["DevOps","Jenkins","CI/CD"],"title":"Jenkins 実践：プライベート導入・プラグイン導入・GitLab 連携 CI","url":"/ja/posts/jenkins-practice/","wordCount":764},{"categories":["DevOps"],"content":"01. GitLab 関連サイト 公式サイト：https://about.gitlab.com/\n国内ミラー：https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/\n02. GitLab のデプロイ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 I. 環境準備 1、OS：CentOS 7.9 2、メモリ：実験用 4G、本番用 8G 以上 3、ファイアウォールを無効化し、SELinux を無効にする II. GitLab の RPM パッケージをダウンロード [root@gitlab ~]# wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm III. GitLab をインストール # インストール中に依存関係のインストールが必要 [root@gitlab ~]# rpm -ivh gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm warning: gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID f27eab47: NOKEY error: Failed dependencies: policycoreutils-python is needed by gitlab-ce-16.9.8-ce.0.el7.x86_64 # 依存関係をインストール [root@gitlab ~]# yum -y install policycoreutils-python # 依存関係インストール後に GitLab のインストールを続行 [root@gitlab ~]# rpm -ivh gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm warning: gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID f27eab47: NOKEY Preparing... ################################# [100%] Updating / installing... 1:gitlab-ce-16.9.8-ce.0.el7 ################################# [100%] IV. 起動前にアクセス用ドメインまたは IP を設定 [root@gitlab ~]# vim /etc/gitlab/gitlab.rb ... external_url \u0026#39;http://11.0.1.200\u0026#39; ... 設定後、以下のコマンドを実行： [root@gitlab ~]# gitlab-ctl reconfigure 03. GitLab のコンポーネント 1 2 3 4 5 6 7 nginx： 静的 Web サーバー gitlab-workhorse: 軽量なリバースプロキシ logrotate： ログ管理ツール postgresql： データベース redis： キャッシュデータベース sidekiq： バックグラウンドのキュージョブを実行（非同期）。（Ruby） unicorn：Rack アプリケーション用 HTTP サーバー。GitLab の Rails アプリはこのサーバーでホストされる。（Ruby Web サーバー、主に Ruby で記述） 04. よく使う GitLab コマンド 1 2 3 4 5 gitlab-ctl start # GitLab を起動（gitlab-ctl reconfigure 後は自動起動） gitlab-ctl status # GitLab 全サービスの稼働状態を確認 gitlab-ctl stop # GitLab サービスを停止 gitlab-ctl stop nginx # 個別のサービスを停止 gitlab-ctl tail # 全サービスのログを表示 05. GitLab Web UI の設定 GitLab へログイン：11.0.1.200\n1. ログインパスワード gitlab-ctl reconfigure 完了後、パスワードの保存場所が表示される：\n2. UI 言語を中国語にする 3. デフォルトパスワードを変更 4. Webhook のローカルネットワーク要求を許可 06. GitLab 実践 1. グループを作成 2. グループ配下にプロジェクトを作成 これで最初のコードリポジトリが作成されたが、中身は空。次にコードをアップロードする\n3. コードをプロジェクトにコミット プロジェクト作成後、blog のコードをこのプロジェクトにアップロードする\nサーバーとコードリポジトリの接続方法は 2 つある\n1 つ目：ユーザー名とパスワードで接続\n2 つ目：SSH 鍵認証（非対話）で接続\n私たちは鍵認証方式を使う：便利でセキュリティも高い\n鍵ペアを生成（ここでは GitLab サーバーを直接使用） 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [root@gitlab ~]#ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory \u0026#39;/root/.ssh\u0026#39;. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:j3FozajJdufxM0ZRtgPa2ZNSwWKvo8bvxbMJl8F5V3M root@gitlab The key\u0026#39;s randomart image is: +---[RSA 2048]----+ | ... | | + = | | + X +E| | =. =.B.+| | S + ++oo| | . + = +. +.| | = o.+o..* | | . . o+o++ + | | ..++oo | +----[SHA256]-----+ 鍵ペアを確認： [root@gitlab ~]# ll .ssh/ total 8 -rw------- 1 root root 1679 May 14 15:02 id_rsa # 秘密鍵 -rw-r--r-- 1 root root 393 May 14 15:02 id_rsa.pub # 公開鍵 [root@gitlab ~]#cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJGpCKL64eidZ3I/nAVNCNJwD8yeDqelZP0GUTwlcp6IdKaZ7wUOIRDCtGn5r+YnOCKNwMhUNzb3VCOSVLDVIE0x53dPrCMK4OKLmZ6OtTYFBveGOZWWwdYyGQITx2eP7zOSBxeW3AnEWcya/UZdiZrYXA/d29DWjMjCt5QAxOit0EWSir1Z4i2MkTPuljOmjk6A55XAoem0WJRdg/d8KKIiCdcGrj4adYq2kNJ8oYH/9QcnpASUW/ANhzrALnLIX2WaH/p0T3gisLvk2KDUe3rVKD3XaKDlyLgWIViQFm3Me6L2e4taRFiu3VdsbfFfzjDevfDtLaqKLOqPtaczlF root@gitlab 生成した公開鍵を GitLab の SSH 鍵管理ページに貼り付ける これでサーバーと GitLab UI 間の SSH 鍵認証が完了。次にコードを blog プロジェクトにプッシュする\nコードをプッシュする方法は 2 つある：\n空のリポジトリをローカルにクローンし、コードをコピーしてからリモート GitLab にコミットする プロジェクト内でリンクアドレスを確認する\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 1. リンクをコピーして実行 [root@gitlab ~]#git clone git@11.0.1.200:dawn/blog.git Cloning into \u0026#39;blog\u0026#39;... The authenticity of host \u0026#39;11.0.1.200 (11.0.1.200)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:Ldn1vBzBEFxynXs0qBNr0XzJ2lTx/0caMuK5yJtb+Zo. ECDSA key fingerprint is MD5:3d:1d:28:3f:33:ec:ee:c1:69:83:af:14:a3:7f:79:ac. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;11.0.1.200\u0026#39; (ECDSA) to the list of known hosts. warning: remote HEAD refers to nonexistent ref, unable to checkout. 2. blog リポジトリがローカルにダウンロードされたことを確認 [root@gitlab ~]#ll total 1176964 drwxr-xr-x 3 root root 18 Oct 1 14:43 blog -rw-r--r-- 1 root root 84579612 Oct 1 14:35 blog_backup_20261001-1435.tar.gz drwxr-xr-x 3 root root 18 Sep 30 19:14 dawn -rw-r--r-- 1 root root 1120627456 Sep 30 23:12 gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm 3. blog ディレクトリに入る [root@gitlab ~]#cd blog/ 4. コードを展開： [root@gitlab blog]#tar xf /root/blog_backup_20261001-1435.tar.gz -C . 5. コードをローカルリポジトリにコミット [root@gitlab blog]#git add . [root@gitlab blog]#git commit -m \u0026#34;DAWN’s Blog\u0026#34; [master (root-commit) 5af4246] DAWN’s Blog 3 files changed, 112 insertions(+) create mode 100644 blog_state.txt create mode 160000 myblog create mode 160000 myblog-deploy 6. コードをリモート GitLab の blog リポジトリにプッシュ GitLab リポジトリを直接クローンしたため、ローカルディレクトリにはすでにリモート blog プロジェクトのアドレスが設定されている リモートリポジトリを確認： [root@gitlab blog]#git remote -v origin git@11.0.1.200:dawn/blog.git (fetch) origin git@11.0.1.200:dawn/blog.git (push) ローカルの master をリモート origin にプッシュ [root@gitlab blog]#git push -u origin master Counting objects: 3, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 1.23 KiB | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@11.0.1.200:dawn/blog.git * [new branch] master -\u0026gt; master Branch master set up to track remote branch master from origin. blog プロジェクトを確認、コードのアップロード成功\nローカル Git リポジトリをリモート GitLab にプッシュ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 1. ローカルリポジトリを設定 [root@gitlab ~]#mkdir dawn [root@gitlab ~]#cd dawn 2. リポジトリを初期化 [root@gitlab dawn]#git init 3. コードをアップロード [root@gitlab dawn]#touch a.txt [root@gitlab dawn]#git add . [root@gitlab dawn]#git commit -m \u0026#34;test_v1\u0026#34; [master (root-commit) 815c600] test_v1 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a.txt 4. GitLab の blog リポジトリをローカルのリモートに設定 [root@gitlab dawn]#git remote add origin git@11.0.1.200:dawn/blog.git 5. ローカル内容をリモートにプッシュ（リモートにすでに内容があるため直接プッシュはエラーになる。リモート内容を保持するため、先に pull してマージしてからプッシュする） [root@gitlab dawn]#git pull origin master warning: no common commits remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From 11.0.1.200:dawn/blog * branch master -\u0026gt; FETCH_HEAD Merge made by the \u0026#39;recursive\u0026#39; strategy. blog_state.txt | 110 ++++++++++++++++++++++++++++++++++++ myblog | 1 + myblog-deploy | 1 + 3 files changed, 112 insertions(+) create mode 100644 blog_state.txt create mode 160000 myblog create mode 160000 myblog-deploy [root@gitlab dawn]#git push -u origin master Counting objects: 6, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 462 bytes | 0 bytes/s, done. Total 5 (delta 1), reused 0 (delta 0) To git@11.0.1.200:dawn/blog.git 5af4246..0242e0a master -\u0026gt; master Branch master set up to track remote branch master from origin. 一般ユーザー dev を作成 作成後、dev のパスワードを変更（ログアウトしないこと。ユーザー画面の編集をクリック）\nその後、dev で GitLab にログイン（初回ログイン時にパスワード変更が必要）\ndev ユーザーを dawn グループに追加 dev サーバーで鍵ペアを生成 1 [root@lb01 ~]#ssh-keygen 生成した公開鍵を dev アカウントの SSH 鍵ページにコピー コードを dev ホスト 11.0.1.5 にクローン 1 2 3 4 5 6 7 8 9 10 11 12 13 [root@lb01 ~]#git clone git@11.0.1.200:dawn/blog.git Cloning into \u0026#39;blog\u0026#39;... The authenticity of host \u0026#39;11.0.1.200 (11.0.1.200)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:Ldn1vBzBEFxynXs0qBNr0XzJ2lTx/0caMuK5yJtb+Zo. ECDSA key fingerprint is MD5:3d:1d:28:3f:33:ec:ee:c1:69:83:af:14:a3:7f:79:ac. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;11.0.1.200\u0026#39; (ECDSA) to the list of known hosts. remote: Enumerating objects: 8, done. remote: Counting objects: 100% (8/8), done. remote: Compressing objects: 100% (6/6), done. remote: Total 8 (delta 1), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (8/8), done. Resolving deltas: 100% (1/1), done. コードを修正してリモートリポジトリにアップロード 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 11.0.1.5 のユーザーを設定 [root@lb01 blog]#git config --global user.email \u0026#34;dev@mail.com\u0026#34; [root@lb01 blog]#git config --global user.name \u0026#34;dev\u0026#34; [root@lb01 blog]#vim a.txt 123 [root@lb01 blog]#git commit -am \u0026#34;123\u0026#34; リモートリポジトリにコミット [root@lb01 blog]#git push -u origin master Counting objects: 5, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 257 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) remote: GitLab: You are not allowed to push code to protected branches on this project.To git@11.0.1.200:dawn/blog.git ! [remote rejected] master -\u0026gt; master (pre-receive hook declined) error: failed to push some refs to \u0026#39;git@11.0.1.200:dawn/blog.git\u0026#39; # master ブランチへのプッシュは許可されていない 他のブランチにプッシュ： 1. dev ブランチを作成 [root@lb01 blog]#git branch dev [root@lb01 blog]#git branch dev * master 2. dev ブランチをリモートにプッシュ [root@lb01 blog]#git push -u origin dev マージリクエスト（MR）\ndev アカウントからマージリクエストを作成 root アカウントでマージを承認し、元の dev ブランチを削除 Web サーバーでコードをダウンロード 1 2 [root@web01 ~]#git clone http://11.0.1.200/dawn/blog.git ユーザー名とパスワードを入力 ","date":"2026-10-01","description":"","objectID":"/ja/posts/gitlab-practice/","readingTime":6,"tags":["DevOps","GitLab","CI/CD"],"title":"GitLab 実践：プライベート導入・SSH 鍵認証・リポジトリ管理","url":"/ja/posts/gitlab-practice/","wordCount":1249},{"categories":["DevOps"],"content":"01. Git のインストールとリポジトリの初期化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [root@gitlab ~]#yum install -y git [root@gitlab ~]#git --version git version 1.8.3.1 [root@gitlab ~]#git config --global user.name \u0026#34;dawn\u0026#34; [root@gitlab ~]#git config --global user.email \u0026#34;dawn@mail.com\u0026#34; [root@gitlab ~]#git config --global color.ui true [root@gitlab ~]#cat .gitconfig [user] name = dawn email = dawn@mail.com [color] ui = true [root@gitlab ~]#mkdir dawn [root@gitlab ~]#cd dawn [root@gitlab dawn]#ll total 0 [root@gitlab dawn]#git init Initialized empty Git repository in /root/dawn/.git/ [root@gitlab dawn]#ll total 0 [root@gitlab dawn]#ll -a total 0 drwxr-xr-x 3 root root 18 Jun 11 10:57 . dr-xr-x---. 4 root root 174 Jun 11 10:57 .. drwxr-xr-x 7 root root 119 Jun 11 10:57 .git 02. Git コマンド 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 1. リポジトリの状態を確認する（常にクリーンに保つ） [root@gitlab dawn]#git status # On branch master # # Initial commit # nothing to commit (create/copy files and use \u0026#34;git add\u0026#34; to track) 2. 通常のファイルを作成する [root@gitlab dawn]#touch a.txt 3. 作業ツリーの内容をステージングする [root@gitlab dawn]#git add a.txt # git add . は作業ツリーの全内容をステージング領域に追加する [root@gitlab dawn]#git add . 4. ステージング領域の内容を削除する [root@gitlab dawn]#git rm --cached a.txt rm \u0026#39;a.txt\u0026#39; 5. ステージングしてローカルリポジトリにコミットする [root@gitlab dawn]#git add a.txt [root@gitlab dawn]#git status # On branch master # # Initial commit # # Changes to be committed: # (use \u0026#34;git rm --cached \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # new file: a.txt # # git commit -m にメッセージを付けてローカルリポジトリにコミットする [root@gitlab dawn]#git commit -m \u0026#34;create a.txt\u0026#34; [master (root-commit) b65d348] create a.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a.txt 状態を確認: [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean ファイル作成 touch a.txt ステージング git add a.txt ローカルリポジトリにコミット git commit -m \u0026#34;xxx\u0026#34; 2. git での削除 [root@gitlab dawn]#git rm a.txt rm \u0026#39;a.txt\u0026#39; [root@gitlab dawn]#git status # On branch master # Changes to be committed: # (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # deleted: a.txt # [root@gitlab dawn]#git commit -m \u0026#34;del a.txt\u0026#34; [master 41fc71b] del a.txt 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 a.txt [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean 注意: 作業ツリーのファイルをステージングした後に取り消したい場合は、ステージング領域から削除する [root@gitlab dawn]#touch c.txt [root@gitlab dawn]#git add c.txt [root@gitlab dawn]#git rm --cached c.txt rm \u0026#39;c.txt\u0026#39; 3. 作業ツリーの内容を復元する [root@gitlab dawn]#git reset HEAD b.txt [root@gitlab dawn]#git checkout -- b.txt 4. git での差分確認 git diff 作業ツリーとステージング領域の差分を比較する [root@gitlab dawn]#git diff diff --git a/b.txt b/b.txt index e69de29..ccc3e7b 100644 --- a/b.txt +++ b/b.txt @@ -0,0 +1 @@ +aaaaa git diff --cached ステージング領域とローカルリポジトリの差分を比較する [root@gitlab dawn]#git diff --cached diff --git a/b.txt b/b.txt index e69de29..ccc3e7b 100644 --- a/b.txt +++ b/b.txt @@ -0,0 +1 @@ +aaaaa 5. ファイル名の変更 [root@gitlab dawn]#git mv b.txt b.bak [root@gitlab dawn]#git status # On branch master # Changes to be committed: # (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # renamed: b.txt -\u0026gt; b.bak # [root@gitlab dawn]#git commit -m \u0026#34;newname b.txt--\u0026gt;b.bak\u0026#34; [master 55335a7] newname b.txt--\u0026gt;b.bak 1 file changed, 0 insertions(+), 0 deletions(-) rename b.txt =\u0026gt; b.bak (100%) [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean 6. 任意のスナップショットにロールバックする すべてのスナップショットを表示: [root@gitlab dawn]#git log --oneline ae6585c xx 55335a7 newname b.txt--\u0026gt;b.bak 09ffe53 modifile b.txt 043a297 newfile b.txt 41fc71b del a.txt b65d348 create a.txt [root@gitlab dawn]#ll total 8 -rw-r--r-- 1 root root 6 Jun 11 12:10 b.bak -rw-r--r-- 1 root root 6 Jun 11 12:07 b.txt git reset --hard でロールバックする [root@gitlab dawn]#git reset --hard b65d348 HEAD is now at b65d348 create a.txt [root@gitlab dawn]#ll total 0 -rw-r--r-- 1 root root 0 Jun 11 12:12 a.txt 7. 過去のすべての操作履歴を確認する: [root@gitlab dawn]#git reflog b65d348 HEAD@{0}: reset: moving to b65d348 ae6585c HEAD@{1}: commit: xx 55335a7 HEAD@{2}: commit: newname b.txt--\u0026gt;b.bak 09ffe53 HEAD@{3}: commit: modifile b.txt 043a297 HEAD@{4}: commit: newfile b.txt 41fc71b HEAD@{5}: commit: del a.txt b65d348 HEAD@{6}: commit (initial): create a.txt [root@gitlab dawn]#git reset --hard ae6585c HEAD is now at ae6585c xx [root@gitlab dawn]#ll total 8 -rw-r--r-- 1 root root 6 Jun 11 12:16 b.bak -rw-r--r-- 1 root root 6 Jun 11 12:16 b.txt Git ブランチ 1. ブランチ一覧を表示する（* は現在のブランチ） [root@gitlab dawn]#git branch * master 2. ブランチを作成する [root@gitlab dawn]#git branch dev [root@gitlab dawn]#git branch dev * master 3. dev ブランチに切り替える [root@gitlab dawn]#git checkout dev Switched to branch \u0026#39;dev\u0026#39; [root@gitlab dawn]#git branch * dev master 4. ブランチ上でファイルを作成し、ローカルリポジトリにコミットする [root@gitlab dawn]#touch aa.txt [root@gitlab dawn]#git add . [root@gitlab dawn]#git commit -m \u0026#34;newfile aa.txt\u0026#34; [dev 2694c7f] newfile aa.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 aa.txt 5. ブランチをマージする まず master ブランチに戻る [root@gitlab dawn]#git checkout master Switched to branch \u0026#39;master\u0026#39; [root@gitlab dawn]#git branch dev * master dev ブランチを master にマージする [root@gitlab dawn]#git merge dev Updating ae6585c..2694c7f Fast-forward aa.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 aa.txt 6. 機能を作り終えたらすぐにブランチを削除する（リモートブランチより遅れるため） [root@gitlab dawn]#git branch -d dev Deleted branch dev (was 2694c7f). [root@gitlab dawn]#git branch * master 7. コンフリクトの解決 ---------------------------------- ファイルの内容を変更しても必ずしもマージを妨げるわけではない master ブランチのファイルを編集して bbbbb を追加する [root@gitlab dawn]#vim b.txt aaaaa bbbbb 1 つのコマンドで dev ブランチの作成と切り替えを同時に行える [root@gitlab dawn]#git checkout -b dev Switched to a new branch \u0026#39;dev\u0026#39; [root@gitlab dawn]# [root@gitlab dawn]# [root@gitlab dawn]#git branch * dev master b.txt の内容を編集する [root@gitlab dawn]#vim b.txt aaaaa bbccc ローカルリポジトリにコミットする [root@gitlab dawn]#git add . [root@gitlab dawn]#git commit -m \u0026#34;modifle bbbccc\u0026#34; master ブランチに戻って dev ブランチをマージする [root@gitlab dawn]#git checkout master Switched to branch \u0026#39;master\u0026#39; [root@gitlab dawn]#git branch dev * master [root@gitlab dawn]#cat b.txt aaaaa bbbbb [root@gitlab dawn]#git merge dev Updating f56faba..dc17f6d Fast-forward b.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) [root@gitlab dawn]#cat b.txt aaaaa bbccc ------------------------------------------------------ コンフリクトが発生するケース dev ブランチを作成する [root@gitlab dawn]#git branch dev master ブランチで b.txt の 3 行目を編集する [root@gitlab dawn]#cat b.txt aaaaa iiiii bbbbb [root@gitlab dawn]#git commit -am \u0026#34;modifile b.txt bbbbb\u0026#34; [master ae4ab87] modifile b.txt bbbbb 1 file changed, 1 insertion(+) dev ブランチに切り替えて b.txt の 3 行目を編集する [root@gitlab dawn]#cat b.txt aaaaa iiiii ccccc ローカルリポジトリにコミットする [root@gitlab dawn]#git commit -am \u0026#34;modifile b.txt ccccc\u0026#34; [dev 925c06c] modifile b.txt ccccc 1 file changed, 1 insertion(+) master ブランチに切り替えてブランチをマージする [root@gitlab dawn]#git checkout master Switched to branch \u0026#39;master\u0026#39; [root@gitlab dawn]#git branch dev * master [root@gitlab dawn]#git merge dev Auto-merging b.txt CONFLICT (content): Merge conflict in b.txt Automatic merge failed; fix conflicts and then commit the result. ファイルを確認すると競合が表示される [root@gitlab dawn]#cat b.txt aaaaa iiiii \u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt; HEAD bbbbb ======= ccccc \u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt; dev 手動で競合を解決し、片方だけ、あるいは両方を残す [root@gitlab dawn]#vim b.txt aaaaa iiiii bbbbb ccccc [root@gitlab dawn]#git commit -am \u0026#34;merge dev\u0026#34; [master 325eef2] merge dev [root@gitlab dawn]# [root@gitlab dawn]# [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean [root@gitlab dawn]#cat b.txt aaaaa iiiii bbbbb ccccc マージ後に dev ブランチを削除する [root@gitlab dawn]#git branch -d dev Deleted branch dev (was 925c06c). ","date":"2026-10-01","description":"","objectID":"/ja/posts/git-practice-notes/","readingTime":7,"tags":["DevOps","Git","バージョン管理"],"title":"Git 実践ノート：インストール・基本コマンド・ブランチ管理","url":"/ja/posts/git-practice-notes/","wordCount":1351},{"categories":["Zabbix","監視・運用"],"content":"1. ログインユーザー数を取得する 1 2 3 4 5 6 7 [root@web02 ~]#w 17:44:18 up 1:17, 2 users, load average: 0.01, 0.02, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 11.0.1.1 16:31 11:46 0.07s 0.07s -bash root pts/1 11.0.1.52 17:07 2.00s 0.04s 0.00s w [root@web02 ~]#w|awk \u0026#39;NR==1{print $4}\u0026#39; 2 2. Zabbix の監視項目として定義する 1 2 3 4 5 6 7 [root@web02 ~]# cat /etc/zabbix/zabbix_agentd.d/system.conf UserParameter=login_number,w|awk \u0026#39;NR==1{print $4}\u0026#39; # zabbix_agentd -p で項目の文法チェックができます [root@web02 ~]#zabbix_agentd -p|grep login_number login_number [t|2] # クライアントを再起動 [root@web02 ~]# systemctl restart zabbix-agent.service 3. Zabbix サーバー側で収集・監視する サーバーからコマンドラインで、監視項目を通じてユーザー定義の値が取得できるかテストします。\n1 2 3 4 # zabbix-get コマンドをインストール [root@zabbix ~]# yum -y install zabbix-get [root@zabbix ~]#zabbix_get -s 172.16.1.8 -k login_number 2 Web ページで監視項目を追加する\n監視項目を確認する\n4. TCP 22 ポートの生存を監視する 監視したい情報に合わせてキー値を選択します。\nTCP ポートが LISTEN 状態かどうかを確認します。戻り値: 0 - 待ち受けなし; 1 - 待ち受け中。\nweb02 の sshd サービスを停止する\n1 [root@web02 ~]# systemctl stop sshd 5. 表示用のカスタム値マッピングを設定する 値マッピングを適用する\n6. サーバーメモリ使用率のカスタム監視 手順 1: カスタム項目を定義し、空き率を取得する\n1 2 3 4 5 6 [root@web02 ~]# cat /etc/zabbix/zabbix_agentd.d/system.conf UserParameter=login_number,w|awk \u0026#39;NR==1{print $4}\u0026#39; UserParameter=mem_free,free|awk \u0026#39;NR==2{print $NF/$2*100}\u0026#39; [root@web02 ~]# systemctl restart zabbix-agent.service [root@web02 ~]#zabbix_agentd -p|grep mem_free mem_free [t|79.8753] 手順 2: サーバー側でキー値の取得をテストし、監視項目を追加する\n1 2 [root@zabbix ~]#zabbix_get -s 172.16.1.8 -k mem_free 79.9775 7. 空きメモリにトリガーを設定する 空きメモリ率が 20% を下回った場合にアラートを発報します。\nテスト: swap パーティションを無効にする\n1 [root@web02 ~]# swapoff -a dd でストレステストを実行しメモリを消費する\n1 [root@web02 ~]# dd if=/dev/zero of=/dev/null bs=1200M count=2048 8. 複数条件トリガーを設定する 両方の条件が同時に満たされた場合にのみアラートを発報します。\nswap 空き率を追加する\n1 2 3 4 [root@web02 ~]# cat /etc/zabbix/zabbix_agentd.d/system.conf UserParameter=login_number,w|awk \u0026#39;NR==1{print $4}\u0026#39; UserParameter=mem_free,free|awk \u0026#39;NR==2{print $NF/$2*100}\u0026#39; UserParameter=swap_free,free -m|awk \u0026#39;NR==3{print $3/$2*100}\u0026#39; トリガー設定を変更する\nその後、再度 dd ストレステストを実行して結果を確認します。\n","date":"2026-09-23","description":"","objectID":"/ja/posts/zabbix-custom-monitor/","readingTime":2,"tags":["Zabbix","カスタム監視","UserParameter","トリガー","値マッピング"],"title":"Zabbix カスタム監視","url":"/ja/posts/zabbix-custom-monitor/","wordCount":233},{"categories":["Zabbix","監視・運用"],"content":"企業の Zabbix 高負荷シナリオでの使用を想定しています。\n1. 独立したデータベースサーバー (11.0.1.52) を用意し MariaDB をインストールする 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@db02 ~]#yum -y install mariadb-server [root@db02 ~]#systemctl enable mariadb --now [root@db02 ~]#mysql Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 2 Server version: 5.5.68-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [(none)]\u0026gt; create database zabbix character set utf8 collate utf8_bin; Query OK, 1 row affected (0.02 sec) MariaDB [(none)]\u0026gt; create user \u0026#39;zabbix\u0026#39;@\u0026#39;%\u0026#39; identified by \u0026#39;zabbix\u0026#39;; Query OK, 0 rows affected (0.10 sec) MariaDB [(none)]\u0026gt; grant all privileges on zabbix.* to \u0026#39;zabbix\u0026#39;@\u0026#39;%\u0026#39;; Query OK, 0 rows affected (0.00 sec) 2. Zabbix サーバーから zabbix データベースをエクスポートし、新しいデータベースへインポートする 1 2 [root@zabbix ~]# mysqldump -uroot -B zabbix \u0026gt; zabbix.sql [root@zabbix ~]# cat zabbix.sql |mysql -h 172.16.1.52 -uzabbix -pzabbix zabbix 3. Web UI のデータベース接続を設定する 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@zabbix ~]# systemctl stop mariadb [root@zabbix ~]# cat /etc/zabbix/web/zabbix.conf.php \u0026lt;?php // Zabbix GUI configuration file. global $DB; $DB[\u0026#39;TYPE\u0026#39;] = \u0026#39;MYSQL\u0026#39;; $DB[\u0026#39;SERVER\u0026#39;] = \u0026#39;172.16.1.52\u0026#39;; $DB[\u0026#39;PORT\u0026#39;] = \u0026#39;0\u0026#39;; $DB[\u0026#39;DATABASE\u0026#39;] = \u0026#39;zabbix\u0026#39;; $DB[\u0026#39;USER\u0026#39;] = \u0026#39;zabbix\u0026#39;; $DB[\u0026#39;PASSWORD\u0026#39;] = \u0026#39;zabbix\u0026#39;; [root@zabbix ~]# grep ^DB /etc/zabbix/zabbix_server.conf DBHost=172.16.1.52 DBName=zabbix DBUser=zabbix DBPassword=zabbix 4. サービスを再起動する 1 [root@zabbix ~]# systemctl restart zabbix-server httpd ","date":"2026-09-23","description":"","objectID":"/ja/posts/zabbix-split-database/","readingTime":2,"tags":["Zabbix","データベース","分割","高負荷"],"title":"Zabbix データベースの分割","url":"/ja/posts/zabbix-split-database/","wordCount":232},{"categories":["Zabbix","監視・運用"],"content":"1. zabbix-agent クライアントをインストールする — サーバー (11.0.1.8) を用意 1 2 3 4 5 6 7 8 リポジトリを設定します： [root@web02 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm サーバー側の yum リポジトリをクライアントへ同期します： [root@zabbix ~]#scp /etc/yum.repos.d/CentOS-SCLo-scl.repo root@172.16.1.8:/etc/yum.repos.d/CentOS-SCLo-scl.repo [root@zabbix ~]#scp /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo root@172.16.1.8:/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo [root@zabbix ~]#scp /etc/yum.repos.d/zabbix.repo root@172.16.1.8:/etc/yum.repos.d/zabbix.repo インストール時にパッケージ競合が発生した場合： [root@web02 ~]# yum -y install centos-release-scl 2. zabbix-agent にサーバー情報を設定し、起動する 1 2 3 4 5 6 [root@web02 ~]# yum -y install zabbix-agent [root@web02 ~]# vim /etc/zabbix/zabbix_agentd.conf Server=172.16.1.71 ServerActive=172.16.1.71 Hostname=web02 [root@web02 ~]# systemctl enable zabbix-agent --now 3. Zabbix から web02 を監視する 4. web02 の監視設定完了 ","date":"2026-09-23","description":"","objectID":"/ja/posts/zabbix-monitor-server/","readingTime":1,"tags":["Zabbix","監視","zabbix-agent","監視設定"],"title":"Zabbix でサーバー情報を監視する","url":"/ja/posts/zabbix-monitor-server/","wordCount":79},{"categories":["Zabbix","監視・運用"],"content":"1. リポジトリを設定する 1 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm 2. zabbix-server と zabbix-agent をインストールする 1 yum -y install zabbix-server-mysql zabbix-agent 3. SCL リポジトリをインストールする（バージョン競合の解決） 1 [root@zabbix ~]# yum -y install centos-release-scl 4. フロントエンドリポジトリを有効化する 1 2 3 4 5 [root@zabbix ~]# vim /etc/yum.repos.d/zabbix.repo [zabbix-frontend] ... enabled=1 ... 5. CentOS-SCLo-scl.repo / CentOS-SCLo-scl-rh.repo の壊れた mirrorlist を Aliyun の baseurl に置き換える 1 2 3 4 5 6 7 8 9 10 [root@zabbix yum.repos.d]#vim CentOS-SCLo-scl-rh.repo [centos-sclo-rh] ... baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh ... [root@zabbix yum.repos.d]#vim CentOS-SCLo-scl.repo [centos-sclo-sclo] ... baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo ... 6. PHP/Apache フロントエンドをインストールする 1 [root@zabbix ~]# yum -y install zabbix-web-mysql-scl zabbix-apache-conf-scl 7. MariaDB データベースをインストールする 1 2 3 [root@zabbix ~]# yum -y install mariadb-server データベースを起動します： [root@zabbix ~]#systemctl enable mariadb --now 8. Zabbix データベースを作成する 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [root@zabbix ~]#mysql -uroot Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 7 Server version: 5.5.68-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [(none)]\u0026gt; create database zabbix character set utf8 collate utf8_bin; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]\u0026gt; create user zabbix@localhost identified by \u0026#39;zabbix\u0026#39;; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]\u0026gt; grant all privileges on zabbix.* to zabbix@localhost; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]\u0026gt; set global log_bin_trust_function_creators = 1; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]\u0026gt; quit Bye 9. データベースを初期化する（Zabbix 起動前に必要なスキーマをインポート） 1 2 3 4 5 [root@zabbix ~]# zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -p zabbix # zabbix のパスワードの入力を求められます [root@zabbix ~]# mysql -uroot MariaDB [(none)]\u0026gt; set global log_bin_trust_function_creators = 0; quit 10. Zabbix のデータベース接続を設定する 1 2 3 4 [root@zabbix ~]# egrep ^DB /etc/zabbix/zabbix_server.conf DBName=zabbix DBUser=zabbix DBPassword=zabbix # コメントを外してパスワードを設定 11. タイムゾーンを設定する 1 2 [root@zabbix ~]# tail -1 /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf php_value[date.timezone] = Asia/Shanghai 12. サービス（server、agent、httpd、php）を起動し、起動時有効化する 1 [root@zabbix ~]# systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm --now 13. Zabbix Web UI に 11.0.1.71/zabbix でアクセスする 14. Zabbix のインストール完了 15. 中国語表示に切り替え、フォントを再設定する Windows のフォントを見つけて、Zabbix のフォントディレクトリにコピーします。\nWindows フォントの保存場所：\nいずれかのフォントをアップロードし、名前を変更します：\n1 2 3 4 5 6 7 8 9 10 [root@zabbix ~]#cd /usr/share/zabbix/assets/fonts/ [root@zabbix fonts]#ls graphfont.ttf simhei.ttf # アップロードしたフォント [root@zabbix fonts]#rm -f graphfont.ttf # 元のフォントを削除 [root@zabbix fonts]#ln -s /usr/share/zabbix/assets/fonts/simhei.ttf graphfont.ttf # アップロードしたフォントにリンク [root@zabbix fonts]#chmod 644 simhei.ttf [root@zabbix fonts]#ll total 9520 lrwxrwxrwx 1 root root 41 Sep 23 01:19 graphfont.ttf -\u0026gt; /usr/share/zabbix/assets/fonts/simhei.ttf -rw-r--r-- 1 root root 9745792 Sep 23 01:18 simhei.ttf ","date":"2026-09-23","description":"","objectID":"/ja/posts/zabbix-install/","readingTime":2,"tags":["Zabbix","監視","CentOS7","インストール"],"title":"Zabbix のインストールとデプロイ","url":"/ja/posts/zabbix-install/","wordCount":398},{"categories":["Kubernetes","運用・デプロイ"],"content":"計画は以下の通りです：\nMaster ノード： ホスト名： master IP アドレス：192.168.8.30\nWorker01 ノード： ホスト名： node1 IP アドレス：192.168.8.31\nWorker02 ノード： ホスト名： node2 IP アドレス：192.168.8.32\n3 つのノードすべてで以下の手順を完了し、3 つのノードの時刻が一致していることを確認してください。\n1. ファイアウォールと SELinux を無効にする 1 2 3 4 [root@master ~]# systemctl disable firewalld.service --now [root@master ~]# vim /etc/selinux/config SELINUX=disabled [root@master ~]# setenforce 0 2. スワップを無効にする 1 2 [root@master ~]# sed -i \u0026#39;/swap/s/^/#/\u0026#39; /etc/fstab [root@master ~]# swapoff -a 3. システムパラメータの設定とカーネルモジュールのロード 1 2 3 4 5 6 7 8 9 10 11 12 [root@master ~]# cat \u0026gt; /etc/modules-load.d/k8s.conf \u0026lt;\u0026lt; EOF overlay br_netfilter EOF [root@master ~]# modprobe overlay [root@master ~]# modprobe br_netfilter [root@master ~]# cat \u0026gt; /etc/sysctl.d/k8s.conf \u0026lt;\u0026lt; EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF [root@master ~]# sysctl --system 4. コンテナランタイム（Containerd）のインストール Kubernetes v1.30 ではコンテナランタイムとして Containerd の使用が推奨されています：\n1 [root@master ~]# yum -y remove runc OS 同梱の yum リポジトリファイルを削除します：\n1 [root@master ~]# rm -rf /etc/yum.repos.d/Cent*.repo ローカル yum リポジトリを設定します：\n1 2 3 4 5 6 7 8 9 10 11 12 [root@master ~]# mount /dev/cdrom /media/ [root@master ~]# cat /etc/fstab | grep iso9660 /dev/cdrom\t/media\tiso9660 defaults 0 0 [root@master ~]# cat /etc/yum.repos.d/dvd.repo [BaseOS] name=BaseOS baseurl=file:///media/BaseOS gpgcheck=0 [AppStream] name=AppStream baseurl=file:///media/AppStream gpgcheck=0 Containerd を設定します：\n1 2 [root@master ~]# yum install -y yum-utils [root@master ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo containerd.io をインストールします：\n1 2 3 4 5 6 7 8 9 10 [root@master ~]# yum install -y containerd.io # 設定ファイルを生成して編集する [root@master ~]# mkdir -p /etc/containerd [root@master ~]# containerd config default \u0026gt; /etc/containerd/config.toml # systemd cgroup ドライバを使用するよう設定を編集する #sed -i \u0026#39;s/SystemdCgroup = false/SystemdCgroup = true/g\u0026#39; /etc/containerd/config.toml # イメージアクセラレーションを設定（任意） #sed -i \u0026#39;s|registry.k8s.io|registry.aliyuncs.com/google_containers|g\u0026#39; /etc/containerd/config.toml # 起動してブート時に有効化する #systemctl enable --now containerd 5. Kubernetes のインストールと設定 1 2 3 4 5 6 7 [root@master yum.repos.d]# cat kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/ enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/repodata/repomd.xml.key 指定バージョンの Kubernetes コンポーネントをインストールします：\n1 2 3 [root@master ~]# yum install -y kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 --disableexcludes=kubernetes # kubelet を起動する [root@master ~]# systemctl enable --now kubelet 6. Kubernetes の初期化 注意：すべてのノードで上記の設定が完了したら、以下の手順は master ノードでのみ実行してください。\n1 2 3 4 5 [root@master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=172.16.0.0/16 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.30.0 --control-plane-endpoint=\u0026#34;192.168.8.30:6443\u0026#34; --upload-certs # kubectl を設定する [root@master ~]# mkdir -p $HOME/.kube [root@master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@master ~]# chown $(id -u):$(id -g) $HOME/.kube/config 7. ワーカーノードを Kubernetes クラスタに参加させる 以下のコマンドをワーカーノードで実行します。注意：ノードごとにトークンと CA 証明書ハッシュが異なる場合があります。お使いのシステムの指示に従ってください。証明書の有効期限が切れている場合もあります。その場合は kubeadm token create --print-join-command で参加コマンドを再生成してください。\n1 2 [root@node1 ~]# kubeadm join 192.168.8.30:6443 --token yfjrsi.60lmqgzobp0b8al3 --discovery-token-ca-cert-hash sha256:f4e3c924918545abfd8148e71a377e086d591c6a59856a496b4b33e0987d9c18 [root@node2 ~]# kubeadm join 192.168.8.30:6443 --token yfjrsi.60lmqgzobp0b8al3 --discovery-token-ca-cert-hash sha256:f4e3c924918545abfd8148e71a377e086d591c6a59856a496b4b33e0987d9c18 8. master ノードへの Calico ネットワークプラグインのインストール 1 2 # Calico ネットワークプラグインをインストールする [root@master ~]# kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml 注意：周知の理由により、Calico イメージのダウンロードに失敗する場合があります。\n当該マニフェストファイルを修正したので、master ノードにダウンロードして適用してください：\nこのファイルは百度網盤（Baidu Netdisk）にアップロードしてあります。ダウンロードリンク：https://pan.baidu.com/s/1BPCFxv0kE0KWb04Qsgy71g （抽出コード：s44k）\n1 [root@master ~]# kubectl apply -f /root/calico-ucloud.yaml インストール完了後、以下を実行します：\n1 2 3 4 5 [root@master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready control-plane 65m v1.30.13 node1 Ready \u0026lt;none\u0026gt; 62m v1.30.0 node2 Ready \u0026lt;none\u0026gt; 62m v1.30.0 上記の結果が表示されれば、Kubernetes のインストールは完了です。\n9. 補足 各ノードで以下のコマンドを実行します：\n1 2 3 4 5 kubectl completion bash \u0026gt; /etc/bash_completion.d/kubectl source /etc/bash_completion.d/kubectl vim /root/.bashrc alias docker=\u0026#39;crictl\u0026#39; source /root/.bashrc 補足：\nkubectl の補完：上の 2 行は kubectl の補完スクリプトを /etc/bash_completion.d/ に書き出します。ただしその前提として、システムに bash-completion パッケージがインストールされていること（yum install -y bash-completion や apt install -y bash-completion）が必要です。インストールされていないと該当ディレクトリが存在せず、補完は機能しません。さらに kubectl 自体もこの 2 行を実行して初めて補完が有効になります（Kubernetes は別途この設定が必要です）。 docker エイリアス：Kubernetes が containerd ランタイムに切り替わったため、コンテナ管理コマンドは docker から crictl に変わります。ここで docker を crictl にエイリアスするのは、docker コマンドに慣れたユーザーの操作性を考慮し、これまでの操作感を維持するためです。 # docker images を実行した際に、以下のエラーが発生した場合：\nKubernetes に以下の警告が表示された場合の解決方法は次の通りです。\nWARN[0000] image connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.\nこの警告は、使用しているコンテナランタイムクライアント（crictl や kubelet など）がデフォルトのエンドポイント設定を使用しており、それが非推奨となっているため明示的に設定する必要があることを示しています。解決手順は以下の通りです：\n1 2 3 4 5 6 7 cat \u0026gt; /etc/crictl.yaml \u0026lt;\u0026lt; EOF runtime-endpoint: unix:///run/containerd/containerd.sock # 使用するコンテナランタイムに合わせて選択 image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false pull-image-on-create: false EOF 補足：\nContainerd を使用する場合、エンドポイントは unix:///run/containerd/containerd.sock です。\nCRI-O を使用する場合、エンドポイントは unix:///run/crio/crio.sock です。\n備考：任意。\nKubernetes を手動でインストールした場合、デフォルトではデータ転送に iptables が使用されます。大規模なシナリオでは、IPVS モードへの変更を推奨します。インストール完了後に IPVS モードに変更する手順は以下の通りです：\n1. 全ノードに ipvsadm パッケージをインストールする 2. 全ノードでモジュールをロードする 1 2 3 4 5 6 7 cat \u0026gt; /etc/modules-load.d/ipvs.conf \u0026lt;\u0026lt; EOF ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack EOF 3. kube-proxy ConfigMap を編集する 1 kubectl edit cm kube-proxy -n kube-system 開いたエディタで、以下のセクションを探して変更します：\n1 2 3 4 5 6 7 apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: \u0026#34;ipvs\u0026#34; # \u0026#34;iptables\u0026#34; から \u0026#34;ipvs\u0026#34; に変更 ipvs: scheduler: \u0026#34;rr\u0026#34; # ロードバランシングアルゴリズム： rr|wrr|lc 4. kube-proxy Pod を強制再起動する すべての kube-proxy Pod を削除して再作成をトリガーします：\n1 #kubectl delete pods -n kube-system -l k8s-app=kube-proxy 5. 新しい Pod が正常に動作していることを確認する 1 2 #kubectl get pods -n kube-system -l k8s-app=kube-proxy # すべての Pod が Running 状態であること 6. IPVS 設定が有効になったことを確認する 1 2 3 4 5 [root@master ~]# ipvsadm -L -n TCP 192.168.8.30:30080 rr -\u0026gt; 10.244.104.3:80 Masq 1 0 0 -\u0026gt; 10.244.104.4:80 Masq 1 0 0 -\u0026gt; 10.244.166.132:80 Masq 1 0 0 ","date":"2026-08-07","description":"","objectID":"/ja/posts/k8s-v1.30-manual-deploy/","readingTime":4,"tags":["Kubernetes","kubeadm","containerd","calico","v1.30","クラスタデプロイ"],"title":"Kubernetes v1.30 クラスタを手動デプロイする（kubeadm 方式）","url":"/ja/posts/k8s-v1.30-manual-deploy/","wordCount":697},{"categories":["仮想化"],"content":" 本記事ではKVM仮想化技術を体系的に紹介し、発展の歴史、デプロイ方法、仮想マシン管理、ネットワークモードの構成、コマンドラインによる自動インストールをカバーします。すべてのコマンドはCentOS/RHEL環境で検証済みです。\nI. KVMの発展の歴史 KVM（Kernel-based Virtual Machine）は、今日のクラウドコンピューティング分野における主流の仮想化技術です。その発展の脈絡を理解することで、業界がなぜ最終的にKVMを選択したのかを理解できます。\n仮想化技術は大きく二つのカテゴリに分けられます：クローズドソース仮想化（例：VMware、Microsoft Hyper-V）とオープンソース仮想化（例：Xen、KVM）。\n初期のオープンソース仮想化の代表はXenでした。AWSとAlibaba Cloudは初期にどちらもXen方式を採用していました。CitrixのXenServerおよびデスクトップクラウド製品FusionAccess（Citrix XenDesktopに対応）もXenをベースにしていました。HuaweiのFusionComputeも6.3バージョン以前はXenを使用していました。\n主なマイルストーンは以下の通りです：\n2008年：Red HatがKVMを買収し、RHEL 5.4で正式にKVMをリリースしました（RHEL 5.0にはXenが搭載されていました）。 2010年：OpenStackプロジェクトが誕生しました。Red HatはIBM、Dell、VMware、Cisco、HPなどと共にKVMオープンソースコミュニティを支援し、オープンソースソフトウェア財団の下でエコシステムを構築しました。同時期にCitrixはCloudStackコミュニティを推進していました。 2014年：RHEL 5.11がリリースされました（RHEL 5.xシリーズのライフサイクル終了、7年間の技術サポート提供、KVMへの無料アップグレードが可能）。 2017年前後：AWSがKVMベースのNitroプラットフォームインスタンスを発表し、Alibaba Cloudおよび世界中の多くのベンダーがKVMを全面的に採用しました。 今日、主要なクラウドサービスプロバイダーの仮想化基盤は基本的にKVMです。HuaweiのFusionCompute 6.3もXenからKVMに切り替えました。2019年にIBMが約340億ドルでRed Hatを買収し、Ansible、GlusterFS、CephなどのRed Hatエコシステムプロジェクトがその傘下に入りました。これはこの技術路線の価値をさらに裏付けるものです。\nII. KVMとは KVMはKernel-based Virtual Machineの略です。その核心的な特徴は以下の通りです：\nカーネルのアップグレードが不要：システム自体のカーネルを直接再利用し、各仮想マシンは一つのプロセスとして実行されます。 軽量な仮想化プラットフォーム：従来の方式に比べてより軽量で効率的です。 統合管理：Xen/KVM仮想化プラットフォームはどちらも統合管理プラットフォームとコマンドラインツールを提供しています。 III. KVMのデプロイ 1. KVM必要パッケージのインストール 前提条件：物理マシンのBIOSで仮想化サポートVT-xを有効にします（ほとんどのコンピュータではデフォルトで有効）。VMware内でネストしてインストールする場合は、VMwareの設定でもVT-xサポートを有効にする必要があります。\n推奨リソース構成：CPU 4コア、メモリ4GB。\n1 2 [root@cloud ~]# yum -y groupinstall \u0026#34;Virtualization*\u0026#34; [root@cloud ~]# systemctl restart libvirtd.service 2. グラフィカルな仮想マシンインストール 本実習ではグラフィカルツールvirt-managerを使用して仮想マシンを作成・インストールします。\n注意：グラフィカルウィザードの操作手順は本記事ではスクリーンショットで示しません。本文はコマンドライン操作を主とし、グラフィカルインターフェースは指示に従ってクリックすれば完了します。また、「ホストマシン」とはKVM仮想マシンを実行するマシンを指します。本実習はVMware内でネスト仮想化を行うため、ここでのホストマシンは物理マシンではなくVMware仮想マシンです。\nまずシステムインストールイメージを準備します：/isosディレクトリを作成し、CentOS 8.4のISOファイルをコピーします。\n1 [root@cloud ~]# mkdir /isos グラフィカル管理インターフェースを起動します：\n1 [root@cloud ~]# virt-manager インターフェースで新規仮想マシンの作成をクリックし、/isosに配置したISOをインストールソースとして選択し、ウィザードに従ってCPU、メモリ、ディスクを構成すればインストールが完了します。インストールされた仮想マシンのディスクファイルはデフォルトで/var/lib/libvirt/images/ディレクトリにserver1.qcow2のような名前で保存されます：\n1 2 3 [root@cloud ~]# cd /var/lib/libvirt/images/ [root@cloud images]# ls server1.qcow2 3. ディスクの作成 前のステップのグラフィカルインストール時にvirt-managerが自動的にディスクを作成します。ここでは手動作成の方法を紹介します。これは後でクラウドイメージの作成や仮想マシンへのディスク追加で使用します。qemu-imgを使用してqcow2形式のディスクを作成します：\n1 [root@cloud ~]# qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/server1.qcow2 10g ヒント：この方法でクラウドイメージを作成する場合、容量が小さいほど作成速度が速くなります。イメージを最小化する方法を研究することをお勧めします。通常、システムディスクは高い性能を要求しません。本当の性能のボトルネックはデータディスクにあります。\n4. ブリッジモードの作成（アップリンク付き仮想スイッチ） ネットワーク構成ディレクトリに移動し、既存のネットワークインターフェースをベースにブリッジ構成をコピーします：\n1 2 [root@cloud ~]# cd /etc/sysconfig/network-scripts/ [root@cloud network-scripts]# cp ifcfg-ens33 ifcfg-br0 ブリッジインターフェースifcfg-br0の編集：\n1 [root@cloud network-scripts]# cat ifcfg-br0 1 2 3 4 5 6 7 8 TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=192.168.8.99 PREFIX=24 GATEWAY=192.168.8.254 DNS1=192.168.8.254 物理インターフェースifcfg-ens33をbr0にブリッジするよう編集：\n1 [root@cloud network-scripts]# cat ifcfg-ens33 1 2 3 4 5 TYPE=Ethernet NAME=ens33 DEVICE=ens33 ONBOOT=yes BRIDGE=br0 ネットワーク構成を再読み込みし、接続を再起動します：\n1 2 3 [root@cloud ~]# nmcli connection reload [root@cloud ~]# nmcli connection down ens33 ; nmcli connection up ens33 [root@cloud ~]# nmcli connection down br0 ; nmcli connection up br0 5. クラウドイメージの作成 要件：カスタムクラウドマシンイメージを作成します。\nKVM仮想マシンのデプロイ完了後、仮想マシンに入って必要なソフトウェアをインストールします：\nローカルyumリポジトリの構成 必要なパッケージのインストール： 1 # yum -y install net-tools vim-enhanced bash-completion cloud-init /etc/cloud/cloud.cfg構成ファイルを編集し、実際の要件に応じてパラメータを調整 /etc/ssh/ssh_host*を削除 init 0でシャットダウン 最後にイメージを圧縮します：\n1 [root@cloud images]# qemu-img convert -c -O qcow2 /var/lib/libvirt/images/server1.qcow2 /isos/server1.qcow2 IV. KVMの管理 virsh対話型インターフェースに入ります：\n1 [root@cloud ~]# virsh 主な仮想マシン管理コマンドは以下の通りです。\nすべての仮想マシンの一覧表示：\n1 2 3 4 [root@cloud ~]# virsh list --all Id Name State ------------------------- - server1 shut off 仮想マシンの起動 / シャットダウン / 強制終了 / 再起動：\n1 2 3 4 [root@cloud ~]# virsh start server1 [root@cloud ~]# virsh shutdown server1 [root@cloud ~]# virsh destroy server1 [root@cloud ~]# virsh reboot server1 6. 仮想マシンコンソールインターフェースへのアクセス KVM仮想マシンに入り、仮想マシンに仮想コンソールを追加することで、ホストマシンからコンソール方式で仮想マシンにアクセスできます。\n仮想マシン内でgrub構成を編集：\n1 [root@VM1 ~]# vim /etc/default/grub GRUB_CMDLINE_LINUXの末尾にconsole=ttyS0を追加：\n1 GRUB_CMDLINE_LINUX=\u0026#34;crashkernel=auto resume=UUID=94e88e69-fad6-4d1f-99cf-0ba83cc793b5 rhgb quiet console=ttyS0\u0026#34; grub構成を再生成し再起動：\n1 2 [root@VM1 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg [root@VM1 ~]# reboot ホストマシンからコンソールに接続：\n1 [root@cloud ~]# virsh console server1 コンソールを終了するショートカットキーはCtrl + ]です。\n7. 構成による仮想マシンへのディスク追加 (1) ディスクファイルの作成：\n1 [root@cloud images]# qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/disk2.qcow2 5g (2) 構成ファイルでディスクを追加：\n1 [root@cloud ~]# vim /etc/libvirt/qemu/server1.xml 構成に以下のdiskセクションを追加：\n1 2 3 4 5 6 \u0026lt;disk type=\u0026#39;file\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;qcow2\u0026#39;/\u0026gt; \u0026lt;source file=\u0026#39;/var/lib/libvirt/images/disk2.qcow2\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vdb\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x07\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; サービスを再起動し仮想マシンを起動：\n1 2 3 [root@cloud ~]# systemctl restart libvirtd.service [root@cloud ~]# virsh start server1 [root@cloud ~]# virsh console server1 KVM仮想マシン内でディスクを確認：\n1 2 3 [root@localhost ~]# fdisk -l /dev/vda /dev/vdb 比較：Xen仮想化ではディスクデバイス名は/dev/xvda、/dev/xvdbです。\n8. KVM仮想マシンの迅速な作成 既存の仮想マシンのXML構成をコピーして迅速に作成：\n1 2 3 4 [root@cloud qemu]# cp server1.xml server2.xml [root@cloud qemu]# uuidgen f3ccabc3-ca4c-41f2-8d6f-e99077c24eeb [root@cloud qemu]# vim server2.xml name、uuid、ディスクパス、MACアドレスなどの主要パラメータを変更：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \u0026lt;domain type=\u0026#39;kvm\u0026#39;\u0026gt; \u0026lt;name\u0026gt;server2\u0026lt;/name\u0026gt; \u0026lt;uuid\u0026gt;f3ccabc3-ca4c-41f2-8d6f-e99077c24eeb\u0026lt;/uuid\u0026gt; \u0026lt;metadata\u0026gt; \u0026lt;disk type=\u0026#39;file\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;qcow2\u0026#39;/\u0026gt; \u0026lt;source file=\u0026#39;/isos/server1.qcow2\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vda\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x04\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; \u0026lt;interface type=\u0026#39;bridge\u0026#39;\u0026gt; \u0026lt;mac address=\u0026#39;52:54:00:96:f6:a2\u0026#39;/\u0026gt; \u0026lt;source bridge=\u0026#39;br0\u0026#39;/\u0026gt; \u0026lt;model type=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/interface\u0026gt; サービスを再起動し新しい仮想マシンを起動：\n1 2 3 [root@cloud ~]# systemctl restart libvirtd.service [root@cloud ~]# virsh start server2 [root@cloud ~]# virsh list --all V. KVMネットワーク構成 KVMには一般的に3つのネットワークモードがあります：NATモード、ホストオンリーモード（Host-Only）、ブリッジモード。\n1. NATモード iptablesのアドレスマスカレードでNATを実現します：\n1 # iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE またはSNATでソースアドレスを指定：\n1 # iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j SNAT --to-source 192.168.8.99 NATルールの確認：\n1 [root@cloud ~]# iptables -t nat -nL デフォルトのネットワーク構成ファイルは/etc/libvirt/qemu/networksにあります：\n1 2 3 [root@cloud networks]# pwd /etc/libvirt/qemu/networks [root@cloud networks]# vim default.xml 2. ホストオンリーモード ホストオンリーモードでは、仮想マシンはホストマシンとのみ通信でき、外部ネットワークにはアクセスできません。\n3. KVM仮想マシンからのインターネットアクセスの有効化 (1) VMwareホストマシンにインターネットアクセス可能なネットワークインターフェースを追加します。\n(2) ホストマシンのOSに入り、デュアルブリッジを構成します。\nifcfg-br0（内部ネットワークブリッジ）：\n1 2 3 4 5 6 TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=192.168.8.99 PREFIX=24 ifcfg-br1（外部ネットワークブリッジ、DHCP）：\n1 2 3 4 5 TYPE=Bridge NAME=br1 DEVICE=br1 ONBOOT=yes BOOTPROTO=dhcp ifcfg-ens33をbr0にブリッジ：\n1 2 3 4 5 TYPE=Ethernet NAME=ens33 DEVICE=ens33 ONBOOT=yes BRIDGE=br0 ifcfg-ens37をbr1にブリッジ：\n1 2 3 4 5 TYPE=Ethernet NAME=ens37 DEVICE=ens37 ONBOOT=yes BRIDGE=br1 サービスを再起動し仮想マシンをシャットダウン：\n1 2 3 4 5 [root@cloud ~]# systemctl restart libvirtd.service [root@cloud ~]# virsh shutdown server1 Domain server1 is being shutdown [root@cloud ~]# virsh shutdown server2 Domain server2 is being shutdown KVM内のserver1仮想マシンのネットワークインターフェースをbr1にブリッジするよう変更し、VM1内でIP取得方式をDHCPに変更：\n1 2 3 4 5 6 7 8 9 10 11 [root@VM1 ~]# nmcli connection modify enp1s0 ipv4.method auto autoconnect yes [root@VM1 ~]# nmcli connection down enp1s0 ; nmcli connection up enp1s0 [root@VM1 ~]# ifconfig enp1s0: flags=4163\u0026lt;UP,BROADCAST,RUNNING,MULTICAST\u0026gt; mtu 1500 inet 192.168.31.158 netmask 255.255.255.0 broadcast 192.168.31.255 inet6 fe80::5054:ff:fe96:f6a1 prefixlen 64 scopeid 0x20\u0026lt;link\u0026gt; ether 52:54:00:96:f6:a1 txqueuelen 1000 (Ethernet) RX packets 1253 bytes 279527 (272.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 119 bytes 17932 (17.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 外部ネットワーク接続のテスト：\n1 2 3 4 5 [root@VM1 ~]# ping www.baidu.com PING www.a.shifen.com (183.2.172.17) 56(84) bytes of data. 64 bytes from 183.2.172.17 (183.2.172.17): icmp_seq=1 ttl=52 time=23.6 ms 64 bytes from 183.2.172.17 (183.2.172.17): icmp_seq=2 ttl=52 time=24.3 ms 64 bytes from 183.2.172.17 (183.2.172.17): icmp_seq=3 ttl=52 time=23.5 ms VI. コマンドラインによるKVM仮想マシンのインストール kickstart自動インストールスクリプトを活用することで、無人での仮想マシンの一括インストールが可能です。\n1. ディスクの作成 1 [root@cloud images]# qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/server3.qcow2 10g 2. 自動インストール virt-installでインストールソースとkickstartファイルを指定：\n1 2 3 4 5 [root@cloud ~]# virt-install -n server3 --memory 2048 --vcpu 2 \\ --disk /var/lib/libvirt/images/server3.qcow2 \\ --network bridge=br1 \\ -l http://192.168.31.96/pub \\ -x inst.ks=http://192.168.31.96/ks/ks01.cfg --vnc kickstart構成ファイルks01.cfgの例：\n1 # vim /var/www/html/ks/ks01.cfg 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #version=RHEL8 # Use text install for fully unattended text repo --name=\u0026#34;AppStream\u0026#34; --baseurl=http://192.168.0.107/pub/AppStream repo --name=\u0026#34;BaseOS\u0026#34; --baseurl=http://192.168.0.107/pub/BaseOS reboot %packages @^minimal-environment kexec-tools %end # Keyboard layouts keyboard --xlayouts=\u0026#39;us\u0026#39; # System language lang en_US.UTF-8 # Network information network --bootproto=dhcp --activate --hostname=server3 --onboot=yes # Use network installation media url --url=http://192.168.0.107/pub/BaseOS # Run the Setup Agent on first boot firstboot --disable ignoredisk --only-use=vda clearpart --all --initlabel autopart # System timezone timezone Asia/Shanghai --utc # Root password rootpw --iscrypted $6$c31XqEglO8ECIli0$enF8T.LW3OknT.178Vb9m2HHYD6dqRdKF2QZia5.G5Tv/zMD//04S2h61oBOKihJZwPIUmWxLc7oXuWtkHQy10 user --name=admin --password=$6$Ey847S5bcqYg8ktk$sd4BJeFF01IFsGOaFwRoqXoYuZ5H1RV3bLC6n6gQGa1tNAjplFDhTnm3Cjw2pgwltIE.xr27X7E/ro4gF2JSG1 --iscrypted --gecos=\u0026#34;admin\u0026#34; %addon com_redhat_kdump --enable --reserve-mb=\u0026#39;auto\u0026#39; %end %anaconda pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty %end 注意：上記のインストールソースアドレス（192.168.0.107）、ホスト名（server3）、およびrootpw、userの後のパスワードハッシュは例です。実際の使用時はご自身の環境のアドレスと生成したパスワード暗号文に置き換えてください。\n","date":"2026-08-02","description":"","objectID":"/ja/posts/kvm-virtualization-guide/","readingTime":5,"tags":["KVM","仮想化","Linux","CentOS"],"title":"KVM仮想化 入門から実戦まで：デプロイ、管理とネットワーク構成","url":"/ja/posts/kvm-virtualization-guide/","wordCount":959},{"categories":["コンテナ技術"],"content":"1. 適切なベースイメージを選択する 1 2 3 4 5 6 7 8 9 10 # ❌ 太大 FROM ubuntu:22.04 # ~77MB FROM python:3.11 # ~1GB # ✅ 推荐 FROM python:3.11-alpine # ~50MB FROM python:3.11-slim # ~130MB # ✅ 最小 FROM gcr.io/distroless/python3 # ~20MB ベースイメージ サイズ ubuntu:22.04 ~77MB python:3.11 ~1GB python:3.11-alpine ~50MB distroless ~20MB 2. マルチステージビルドを使用する 最も効果的な最適化手法：コンパイルステージでは大きなイメージを使い、実行ステージでは成果物だけをコピーします。\n1 2 3 4 5 6 7 8 9 10 11 # 阶段 1：编译 FROM golang:1.21 AS builder WORKDIR /app COPY . . RUN go build -o myapp # 阶段 2：运行 FROM alpine:3.18 WORKDIR /app COPY --from=builder /app/myapp . CMD [\u0026#34;./myapp\u0026#34;] Go アプリケーションが ~1GB から ~15MB に縮小されます。\n3. RUN 命令を統合する 1 2 3 4 5 6 7 8 9 10 11 12 # ❌ 多个层 RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y wget RUN rm -rf /var/lib/apt/lists/* # ✅ 合并为一个层 RUN apt-get update \u0026amp;\u0026amp; \\ apt-get install -y --no-install-recommends \\ curl \\ wget \u0026amp;\u0026amp; \\ rm -rf /var/lib/apt/lists/* 4. ビルドキャッシュのクリーンアップ 1 2 3 4 5 6 7 8 9 # Python - 禁用 pip 缓存 RUN pip install --no-cache-dir -r requirements.txt # Node.js - 清理 npm 缓存 RUN npm ci --only=production \u0026amp;\u0026amp; \\ npm cache clean --force # Go - 去除调试信息 RUN go build -ldflags=\u0026#34;-s -w\u0026#34; -o myapp 5. .dockerignore を使用する 1 2 3 4 5 6 7 8 9 10 11 # .dockerignore .git node_modules *.md .env .vscode __pycache__ *.pyc dist build coverage 1 2 # 检查上下文大小 docker build --no-cache -t test . 2\u0026gt;\u0026amp;1 | grep \u0026#34;Sending build context\u0026#34; 6. 必要なパッケージのみインストールする 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # ❌ 运行镜像里装了编译工具 FROM ubuntu:22.04 RUN apt-get install -y build-essential gcc make cmake COPY . . RUN make \u0026amp;\u0026amp; make install CMD [\u0026#34;./myapp\u0026#34;] # ✅ 编译和运行分离 FROM ubuntu:22.04 AS builder RUN apt-get install -y build-essential gcc make COPY . . RUN make \u0026amp;\u0026amp; make install FROM ubuntu:22.04 COPY --from=builder /app/myapp . CMD [\u0026#34;./myapp\u0026#34;] 7. \u0026ndash;no-install-recommends を使用する 1 2 3 4 5 # ❌ 安装了所有推荐包 RUN apt-get install -y curl # ✅ 只装必须的包（减少约 50% 依赖） RUN apt-get install -y --no-install-recommends curl 8. 静的リソースの圧縮 1 2 3 4 5 6 7 8 9 10 11 # 压缩 JavaScript RUN uglifyjs app.js -o app.min.js # 压缩 CSS RUN cssnano app.css app.min.css # 压缩图片 RUN find . -name \u0026#34;*.png\u0026#34; -exec optipng {} \\; # Go 二进制去除调试信息 RUN go build -ldflags=\u0026#34;-s -w\u0026#34; -o myapp 9. Squash でレイヤーを統合する 1 2 # 合并所有层为一层，去除中间层的重复文件 docker build --squash -t myapp:slim . /etc/docker/daemon.json で experimental 機能を有効にする必要があります。\n10. イメージレイヤーを分析する 1 2 3 4 5 6 7 # 使用 dive 工具分析每层大小和内容 docker run --rm -it \\ -v /var/run/docker.sock:/var/run/docker.sock \\ wagoodman/dive myapp:latest # 或使用 docker history docker history myapp:latest 実践例：Python アプリケーション 1 2 3 4 5 6 # ❌ 优化前（1.2GB） FROM python:3.11 WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 1 2 3 4 5 6 7 8 9 10 11 12 # ✅ 优化后（150MB，缩小 87%） FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --user -r requirements.txt FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 実践例：Node.js アプリケーション 1 2 3 4 5 6 # ❌ 优化前（1.1GB） FROM node:18 WORKDIR /app COPY . . RUN npm install CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 1 2 3 4 5 6 7 8 9 10 11 12 # ✅ 优化后（180MB，缩小 84%） FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM node:18-alpine WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY . . USER node CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 推奨ツール ツール 用途 dive イメージの各レイヤーの内容とサイズを分析 docker-slim イメージを自動的にスリム化 hadolint Dockerfile の静的チェック trivy イメージのセキュリティスキャン ","date":"2026-07-30","description":"10 の実証済みテクニックで、Docker イメージサイズを 90% 以上削減します。","objectID":"/ja/posts/dockerfile-smaller-image/","readingTime":3,"tags":["Docker","Dockerfile","イメージ最適化","コンテナ化"],"title":"Dockerfile のビルドイメージが大きすぎる？10 のテクニックでイメージを 90% スリム化","url":"/ja/posts/dockerfile-smaller-image/","wordCount":598},{"categories":["コンテナ技術"],"content":"1. 命令の順序を適切に配置する（キャッシュの活用） 変更頻度の低い命令を前に、変更頻度の高い命令を後に配置します。あるレイヤーのキャッシュが無効になると、以降のすべてのレイヤーが再ビルドされます。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 # ❌ 错误：每次改代码都要重新装依赖 FROM node:18-alpine WORKDIR /app COPY . . # 代码经常变 RUN npm ci --production # 依赖很少变 CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] # ✅ 正确：依赖变化时才重新安装 FROM node:18-alpine WORKDIR /app COPY package.json package-lock.json ./ # 依赖定义（很少变） RUN npm ci --production # 安装依赖（很少变） COPY . . # 代码（经常变） CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 1 2 # 检查缓存命中情况 docker build -t myapp . 2\u0026gt;\u0026amp;1 | grep -E \u0026#34;(CACHED|Using cache)\u0026#34; 2. .dockerignore でコンテキストを削減する docker build は .git や node_modules など不要なファイルを含むディレクトリ全体を Docker daemon に送信します。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # .dockerignore .git .github .vscode .idea node_modules dist build *.md *.log .env .env.local .DS_Store coverage .nyc_output 1 2 3 4 # 检查上下文大小 docker build --no-cache -t test . 2\u0026gt;\u0026amp;1 | grep \u0026#34;Sending build context\u0026#34; # 优化前：Sending build context to Docker daemon 1.2GB # 优化后：Sending build context to Docker daemon 50MB 3. 軽量なベースイメージを使用する ベースイメージ サイズ 説明 ubuntu:22.04 ~77MB 完全な Ubuntu python:3.11 ~1GB 完全な Python を含む python:3.11-slim ~130MB スリム版 python:3.11-alpine ~50MB Alpine 版 1 2 3 4 5 6 7 8 # ❌ 太大 FROM python:3.11 # 1GB # ✅ 推荐 FROM python:3.11-slim # 130MB # ✅ 最小（注意 musl 兼容性问题） FROM python:3.11-alpine # 50MB Alpine は glibc ではなく musl を使用するため、一部のソフトウェアで互換性の問題が生じる可能性があります。問題に遭遇した場合は slim 版を選択してください。\n4. RUN 命令を統合してレイヤー数を削減する 各 RUN は新しいレイヤーを作成し、レイヤーが多いほどビルドが遅くなり、イメージも大きくなります。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 # ❌ 5 个层 RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y wget RUN apt-get clean RUN rm -rf /var/lib/apt/lists/* # ✅ 1 个层 RUN apt-get update \u0026amp;\u0026amp; \\ apt-get install -y --no-install-recommends \\ curl \\ wget \u0026amp;\u0026amp; \\ apt-get clean \u0026amp;\u0026amp; \\ rm -rf /var/lib/apt/lists/* 1 2 # 检查镜像层数 docker history myapp:latest 5. マルチステージビルドを使用する あるステージでビルドを行い、別のステージで実行し、必要なファイルだけをコピーします。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 阶段 1：构建 FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o app . # 阶段 2：运行（只有 ~15MB） FROM alpine:3.18 RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/app . EXPOSE 8080 CMD [\u0026#34;./app\u0026#34;] 方式 イメージサイズ ビルド時間 シングルステージ ~1.2GB 5 分 マルチステージ ~15MB 2 分 6. BuildKit でビルドを高速化する BuildKit は並列ビルドと高度なキャッシュをサポートしています。\n1 2 3 4 5 6 7 # 启用 BuildKit export DOCKER_BUILDKIT=1 # 或在 /etc/docker/daemon.json 中永久配置 # { # \u0026#34;features\u0026#34;: { \u0026#34;buildkit\u0026#34;: true } # } 1 2 3 4 5 6 7 8 9 10 # 使用缓存挂载（BuildKit 特性） # syntax=docker/dockerfile:1 FROM node:18-alpine WORKDIR /app COPY package.json package-lock.json ./ # 缓存挂载避免每次重新下载依赖 RUN --mount=type=cache,target=/root/.npm \\ npm ci --production COPY . . CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 1 2 # 检查 BuildKit 是否启用 docker build --progress=plain -t myapp . 2\u0026gt;\u0026amp;1 | head -5 7. キャッシュのインポート・エクスポートを使用する CI/CD では、キャッシュは毎回のビルド後に失われます。キャッシュのインポート・エクスポートを使うことで、ビルド間でキャッシュを保持できます。\n1 2 3 4 5 6 7 8 9 10 11 # 导出到本地 docker build \\ --cache-from type=local,src=/tmp/cache \\ --cache-to type=local,dest=/tmp/cache \\ -t myapp . # 使用注册表作为缓存 docker build \\ --cache-from type=registry,ref=myregistry/myapp:cache \\ --cache-to type=registry,ref=myregistry/myapp:cache,mode=max \\ -t myapp . 1 2 3 4 5 6 7 8 9 # GitHub Actions 示例 - name: Build and push uses: docker/build-push-action@v5 with: context: . push: true tags: myapp:latest cache-from: type=gha cache-to: type=gha,mode=max 8. 依存関係の並列インストール 1 2 3 4 5 6 7 8 9 10 11 12 # Node.js - npm ci 比 npm install 快 RUN npm ci --production # Python - 禁用缓存 RUN pip install --no-cache-dir -r requirements.txt # Go - 并行下载模块 RUN go mod download # Rust - 使用 cargo-chef COPY --from=chef /app/recipe.json recipe.json RUN cargo chef cook --release --recipe-path recipe.json 9. ビルドキャッシュと一時ファイルのクリーンアップ 同じ RUN 命令内でクリーンアップを行い、ファイルがレイヤーに残らないようにします。\n1 2 3 4 5 6 7 8 9 10 11 12 # ✅ 正确：同一层中清理 RUN apt-get update \u0026amp;\u0026amp; \\ apt-get install -y --no-install-recommends build-essential \u0026amp;\u0026amp; \\ make \u0026amp;\u0026amp; make install \u0026amp;\u0026amp; \\ apt-get purge -y --auto-remove build-essential \u0026amp;\u0026amp; \\ apt-get clean \u0026amp;\u0026amp; \\ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # ❌ 错误：清理在另一层，文件仍然存在 RUN apt-get update \u0026amp;\u0026amp; apt-get install -y build-essential RUN make \u0026amp;\u0026amp; make install RUN apt-get clean # 太晚了！前面的层已经包含了文件 各言語のクリーンアップコマンド：\n1 2 3 4 5 6 7 8 # Node.js RUN npm ci --production \u0026amp;\u0026amp; npm cache clean --force # Python RUN pip install --no-cache-dir -r requirements.txt # Go RUN go build -o app . \u0026amp;\u0026amp; go clean -cache 10. 特定バージョンのタグを使用する 1 2 3 4 5 6 7 8 # ❌ latest 可能变化，缓存不可预测 FROM node:latest # ✅ 特定版本 FROM node:18.17.0-alpine3.18 # ✅ 更安全：使用 SHA256 摘要 FROM node:18.17.0-alpine3.18@sha256:abc123... イメージレイヤーの詳細 1 2 # 查看镜像层历史 docker history \u0026lt;image-name\u0026gt; 新しいレイヤーを作成する命令：FROM、RUN、COPY、ADD\n新しいレイヤーを作成しない命令（メタデータのみ）：CMD、ENTRYPOINT、ENV、EXPOSE、WORKDIR、USER、LABEL、ARG、VOLUME\n1 2 3 4 5 6 7 8 9 10 11 # 这会创建 4 个层 FROM node:18-alpine # 层 1 RUN apk add --no-cache curl # 层 2 COPY package.json . # 层 3 RUN npm install # 层 4 # 这些指令不增加层 WORKDIR /app # 无层 ENV NODE_ENV=production # 无层 EXPOSE 3000 # 无层 CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] # 无层 最適化効果の比較 1 2 3 4 5 6 7 8 9 # ❌ 优化前（8 分钟，1.2GB） FROM ubuntu:22.04 RUN apt-get update RUN apt-get install -y python3 python3-pip RUN apt-get install -y build-essential WORKDIR /app COPY . . RUN pip3 install -r requirements.txt CMD [\u0026#34;python3\u0026#34;, \u0026#34;app.py\u0026#34;] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # ✅ 优化后（1.5 分钟，150MB） # syntax=docker/dockerfile:1 FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN --mount=type=cache,target=/root/.cache/pip \\ pip install --no-cache-dir -r requirements.txt FROM python:3.11-slim WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY . . EXPOSE 8000 CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 指標 最適化前 最適化後 改善 ビルド時間 8 分 1.5 分 81% ⬇️ イメージサイズ 1.2GB 150MB 87% ⬇️ コンテキストサイズ 500MB 50MB 90% ⬇️ キャッシュヒット率 10% 90% 80% ⬆️ 監視とデバッグ 1 2 3 4 5 6 7 8 9 10 11 # 显示详细构建时间 time docker build -t myapp . # BuildKit 详细进度 DOCKER_BUILDKIT=1 docker build --progress=plain -t myapp . # 分析镜像层 docker history myapp:latest # 使用 dive 工具深入分析 dive myapp:latest ","date":"2026-07-30","description":"10 の実証済みテクニックで、キャッシュ戦略からマルチステージビルドまで、Docker のビルド時間を大幅に短縮します。","objectID":"/ja/posts/dockerfile-faster-build/","readingTime":5,"tags":["Docker","Dockerfile","パフォーマンス最適化","CI/CD"],"title":"Dockerfile のビルドをより速くするには？10 の実用的な最適化テクニック","url":"/ja/posts/dockerfile-faster-build/","wordCount":967},{"categories":["コンテナ技術"],"content":"1. 基本構文 両者の構文はほぼ同じですが、動作には大きな違いがあります：\n1 2 3 4 5 # COPY - 纯粹的文件复制，不做任何额外处理 COPY [--chown=\u0026lt;user\u0026gt;:\u0026lt;group\u0026gt;] \u0026lt;src\u0026gt;... \u0026lt;dest\u0026gt; # ADD - 支持自动解压和远程 URL，但行为不可预测 ADD [--chown=\u0026lt;user\u0026gt;:\u0026lt;group\u0026gt;] \u0026lt;src\u0026gt;... \u0026lt;dest\u0026gt; 2. 圧縮ファイルの自動解凍 ADD はローカルの圧縮ファイルを自動的に解凍しますが、COPY は解凍しません：\n1 2 3 4 5 6 7 # ADD 自动解压 .tar.gz ADD app.tar.gz /opt/app/ # 结果：/opt/app/ 下是解压后的内容 # COPY 只复制文件本身 COPY app.tar.gz /opt/app/ # 结果：/opt/app/app.tar.gz 是原始压缩包 対応する圧縮形式：.tar、.tar.gz/.tgz、.tar.bz2、.tar.xz\n圧縮ファイル自体を解凍せずにコピーしたい場合は、COPY を使う必要があります。\n3. リモート URL のダウンロード ADD は URL から直接ファイルをダウンロードできますが、COPY はサポートしていません：\n1 2 3 4 5 # ADD 可以下载远程文件（但不推荐） ADD https://example.com/app.tar.gz /opt/ # COPY 不支持 URL COPY https://example.com/app.tar.gz /opt/ # 报错！ リモートファイルのダウンロードには RUN + curl で ADD を代替することを推奨します。ADD によるダウンロードはビルドキャッシュを利用できず、エラーハンドリングもなく、整合性の検証もできないためです。\n1 2 3 4 # 推荐：RUN + curl RUN curl -fsSL -o /tmp/app.tar.gz https://example.com/app.tar.gz \\ \u0026amp;\u0026amp; tar -xzf /tmp/app.tar.gz -C /opt/ \\ \u0026amp;\u0026amp; rm /tmp/app.tar.gz 4. ディレクトリの自動作成 どちらも存在しない中間ディレクトリを自動的に作成します：\n1 2 3 4 5 6 # 如果 /etc/myapp/config/ 不存在，会自动创建 COPY app.conf /etc/myapp/config/ ADD app.conf /etc/myapp/config/ # 不需要手动 mkdir # RUN mkdir -p /etc/myapp/config ← 多余 5. ビルドキャッシュの動作 1 2 3 4 5 # COPY - 严格匹配文件内容，内容变了才缓存失效 COPY config/app.conf /etc/app/ # ADD - 压缩文件内容相同时缓存仍然有效 ADD app.tar.gz /opt/app/ シナリオ COPY ADD ファイル内容の変化 キャッシュ無効 キャッシュ無効 ファイルメタデータの変化 キャッシュ無効 キャッシュ無効 圧縮ファイルの内容が同じ N/A キャッシュ有効 6. 機能比較 特性 COPY ADD ローカルファイルのコピー ✅ ✅ ディレクトリのコピー ✅ ✅ ワイルドカードのサポート ✅ ✅ ディレクトリの自動作成 ✅ ✅ 圧縮ファイルの自動解凍 ❌ ✅ リモート URL のサポート ❌ ✅ 意味の明確さ ✅ 高 ❌ 低 推奨使用 ✅ 第一選択 ⚠️ 特定シナリオ 7. 使用シナリオ COPY が適しているケース：\n1 2 3 4 5 6 7 8 9 # 复制配置文件 COPY nginx.conf /etc/nginx/nginx.conf # 复制应用代码 COPY src/ /app/src/ COPY package.json /app/ # 多阶段构建中复制二进制 COPY --from=builder /app/build/app /usr/local/bin/ ADD は自動解凍が必要なシナリオのみに適しています：\n1 2 3 4 5 # 合理使用 ADD ADD node-v18.17.0-linux-x64.tar.gz /usr/local/ # 普通文件不要用 ADD ADD app.conf /etc/app/ # ← 用 COPY 代替 8. ベストプラクティス 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 规则 1：默认用 COPY COPY requirements.txt /app/ # ✅ ADD requirements.txt /app/ # ❌ 没必要 # 规则 2：只在需要解压时用 ADD ADD node-v18.tar.gz /usr/local/ # ✅ 需要解压 # 规则 3：远程文件用 RUN + curl RUN curl -fsSL -o /tmp/app.tar.gz https://example.com/app.tar.gz \\ \u0026amp;\u0026amp; tar -xzf /tmp/app.tar.gz -C /opt/ \\ \u0026amp;\u0026amp; rm /tmp/app.tar.gz # ✅ ADD https://example.com/app.tar.gz /opt/ # ❌ # 规则 4：用 .dockerignore 减少上下文 # .dockerignore # .git # node_modules # *.md # .env # 规则 5：合理安排 COPY 顺序利用缓存 COPY package.json package-lock.json ./ # 先复制依赖（变化少） RUN npm ci --production COPY . . # 再复制代码（变化多） 9. よくある落とし穴 1 2 3 4 5 6 7 8 9 10 # 陷阱 1：意外的自动解压 ADD app.tar.gz /opt/app/ # 你以为复制了文件，实际解压成了目录 # 陷阱 2：远程文件无法缓存 ADD https://github.com/user/repo/releases/download/v1.0/app.tar.gz /tmp/ # 每次构建都重新下载 # 陷阱 3：权限问题 COPY --chown=app:app src/ /app/src/ # 指定所有者 10. 選択の判断基準 1 2 3 4 5 6 7 需要复制文件？ ├── 本地压缩文件且需要解压？ │ └── 用 ADD ├── 本地普通文件？ │ └── 用 COPY └── 远程文件？ └── 用 RUN + curl ","date":"2026-07-30","description":"COPY と ADD はどちらもファイルをコピーできますが、動作に大きな違いがあります。本記事では比較とサンプルを通じて両者の違いを明確に解説します。","objectID":"/ja/posts/dockerfile-copy-vs-add/","readingTime":3,"tags":["Docker","Dockerfile","コンテナ化"],"title":"Dockerfile における COPY と ADD の違いを詳しく解説","url":"/ja/posts/dockerfile-copy-vs-add/","wordCount":456},{"categories":["技術チュートリアル"],"content":"1. 環境要件 OS: CentOS 7/8/Stream 9 Node.js: v18 以上 メモリ: 2GB 以上を推奨 ネットワーク: Anthropic API へのアクセスが必要 2. Node.js のインストール 1 2 3 4 5 6 7 8 9 # 安装 NodeSource 仓库 curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash - # 安装 Node.js sudo yum install -y nodejs # 检查 node -v npm -v Node.js のバージョンが低い場合は、nvm でバージョンを管理します：\n1 2 3 4 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash source ~/.bashrc nvm install 20 nvm use 20 3. Claude Code のインストール 1 2 3 4 5 # 全局安装 npm install -g @anthropic-ai/claude-code # 检查 claude --version 権限の問題が発生した場合、2 つの解決策があります：\n1 2 3 4 5 6 7 8 # 方案一：sudo sudo npm install -g @anthropic-ai/claude-code # 方案二：修改 npm 全局目录（推荐） mkdir -p ~/.npm-global npm config set prefix \u0026#34;~/.npm-global\u0026#34; echo \u0026#39;export PATH=~/.npm-global/bin:$PATH\u0026#39; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc 4. API Key の設定 1 2 3 4 5 6 # 方式一：环境变量（推荐） echo \u0026#39;export ANTHROPIC_API_KEY=\u0026#34;your-api-key-here\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc # 检查 echo $ANTHROPIC_API_KEY 方法 2：claude を直接実行すると、初回起動時に API Key の入力が求められます。\n5. 基本的な使い方 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 启动交互式会话 cd /path/to/your/project claude # 直接提问（非交互模式） claude -p \u0026#34;写一个 Python 脚本，统计当前目录下所有文件的数量\u0026#34; # 分析代码 cat main.py | claude -p \u0026#34;分析这段代码的潜在问题\u0026#34; # 查看/修改配置 claude config # 更新到最新版本 claude update コマンド 説明 claude インタラクティブセッションを開始 claude -p \u0026quot;質問\u0026quot; 直接質問、非インタラクティブモード claude config 設定の確認/変更 claude update 最新バージョンに更新 6. ネットワーク問題のトラブルシューティング Anthropic API への接続がタイムアウトする場合：\n1 2 3 4 5 6 # 配置代理 export https_proxy=\u0026#34;http://your-proxy:port\u0026#34; export http_proxy=\u0026#34;http://your-proxy:port\u0026#34; # 测试连通性 curl -s https://api.anthropic.com/ | head -5 7. セキュリティの推奨事項 1 2 3 4 5 6 7 8 9 # 不要硬编码 API Key，始终用环境变量 echo \u0026#39;export ANTHROPIC_API_KEY=\u0026#34;sk-ant-xxx\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.bashrc # ✅ # ANTHROPIC_API_KEY=sk-ant-xxx 写在代码里 # ❌ # 限制文件权限 chmod 600 ~/.bashrc # 检查是否泄露 grep -r \u0026#34;ANTHROPIC_API_KEY\u0026#34; --include=\u0026#34;*.py\u0026#34; --include=\u0026#34;*.js\u0026#34; . ","date":"2026-07-04","description":"CentOS 上でゼロから Claude Code をデプロイし、Node.js のインストール、API Key の設定、よくある問題のトラブルシューティングまでカバーします。","objectID":"/ja/posts/centos-deploy-claude-code/","readingTime":2,"tags":["Claude Code","CentOS","AI","デプロイ"],"title":"CentOS に Claude Code をデプロイする完全ガイド","url":"/ja/posts/centos-deploy-claude-code/","wordCount":281},{"categories":null,"content":"flannel 実践：Docker クロスホストコンテナネットワークをゼロから構築 一、ネットワーク環境の計画 etcd ホスト IP：192.168.8.88 ホスト名：docker-network Host1 IP：192.168.8.188 ホスト名：web01 Host2 IP：192.168.8.99 ホスト名：web02 二、etcd ホストの設定 ステップ 1：etcd のダウンロードと解凍 github.com から etcd-v3.6.0-linux-amd64.tar.gz パッケージをダウンロードします パッケージを etcd ホストの /root ディレクトリにコピーして解凍します： 1 [root@docker-network ~]# tar -zxvf etcd-v3.6.0-linux-amd64.tar.gz ステップ 2：etcd 実行ファイルのインストール 1 2 [root@docker-network ~]# cd etcd-v3.6.0-linux-amd64 [root@docker-network etcd-v3.6.0-linux-amd64]# cp etcd* /usr/local/bin/ ステップ 3：データディレクトリの作成 1 [root@docker-network ~]# mkdir /var/lib/etcd ステップ 4：etcd サービスの設定と起動 etcd.service ファイルを作成します： 1 [root@docker-network ~]# vim /usr/lib/systemd/system/etcd.service 1 2 3 4 5 6 [Unit] Description=etcd_service [Service] ExecStart=/usr/local/bin/etcd --name etcd1 --data-dir /var/lib/etcd --listen-client-urls http://192.168.8.88:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.8.88:2379,http://127.0.0.1:2379 [Install] WantedBy=multi-user.target システムサービス設定をリロードして etcd を起動します： 1 2 3 [root@docker-network ~]# systemctl daemon-reload [root@docker-network ~]# systemctl enable etcd.service [root@docker-network ~]# systemctl restart etcd.service etcd のリスニング状態を確認します： 1 2 3 [root@docker-network ~]# netstat -tulnp |grep :2379 tcp 0 0 192.168.8.88:2379 0.0.0.0:* LISTEN 1912/etcd tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 1912/etcd ステップ 5：etcd に flannel ネットワーク設定を追加 1 etcdctl --endpoints http://127.0.0.1:2379 put /coreos.com/network/config \u0026#39;{\u0026#34;Network\u0026#34;: \u0026#34;172.16.0.0/16\u0026#34;, \u0026#34;SubnetLen\u0026#34;: 24, \u0026#34;SubnetMin\u0026#34;: \u0026#34;172.16.1.0\u0026#34;,\u0026#34;SubnetMax\u0026#34;: \u0026#34;172.16.10.0\u0026#34;, \u0026#34;Backend\u0026#34;: {\u0026#34;Type\u0026#34;: \u0026#34;vxlan\u0026#34;}}\u0026#39; 1 etcdctl --endpoints http://192.168.8.88:2379 get /coreos.com/network/config 設定の説明：\nNetwork：Flannel アドレスプール SubnetLen：単一のホストに割り当てる docker0 のサブネットマスク長（24ビットは 255.255.255.0） SubnetMin/SubnetMax：割り当て可能なサブネット範囲（例：172.16.1.0/24 から 172.16.10.0/24） Backend：データ転送モード（vxlan はクロスホスト通信をサポート） ステップ 6：ファイアウォールの無効化 1 2 [root@docker-network ~]# systemctl disable firewalld [root@docker-network ~]# systemctl stop firewalld 三、web01 ホストの設定（Host1: 192.168.8.188） ステップ 1：flannel のダウンロードと解凍 flannel-v0.26.7-linux-amd64.tar.gz をホストにダウンロードします ファイルを解凍します： 1 [root@web01 ~]# tar -zxvf flannel-v0.26.7-linux-amd64.tar.gz ステップ 2：flannel 実行ファイルのインストール 1 [root@web01 ~]# cp -p flanneld mk-docker-opts.sh /usr/local/bin/ ステップ 3：flannel サービスの設定と起動 flanneld.service ファイルを作成します： 1 [root@web01 ~]# vim /usr/lib/systemd/system/flanneld.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [Unit] Description=Flanneld Documentation=https://github.com/coreos/flannel After=network.target Before=docker.service [Service] User=root ExecStartPost=/usr/local/bin/mk-docker-opts.sh ExecStart=/usr/local/bin/flanneld --etcd-endpoints=http://192.168.8.88:2379 --iface=192.168.8.188 --ip-masq=true --etcd-prefix=/coreos.com/network Restart=on-failure Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target パラメータの説明：\n--iface=192.168.8.188：本機の etcd 接続用 IP を指定 --etcd-endpoints：etcd サーバーのアドレス サービス設定をリロードして flannel を起動します：\n1 2 3 [root@web01 ~]# systemctl daemon-reload [root@web01 ~]# systemctl enable flanneld.service [root@web01 ~]# systemctl restart flanneld.service ステップ 4：flannel ネットワークインターフェースの確認 1 [root@web01 ~]# ifconfig flannel.1 インターフェースが表示されるはずです（出力例）：\n1 2 3 4 5 6 7 8 flannel.1: flags=4163\u0026lt;UP,BROADCAST,RUNNING,MULTICAST\u0026gt; mtu 1450 inet 172.16.5.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::f06c:96ff:fefe:b7ab prefixlen 64 scopeid 0x20\u0026lt;link\u0026gt; ether f2:6c:96:fe:b7:ab txqueuelen 0 (Ethernet) RX packets 315 bytes 26460 (25.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 314 bytes 34636 (33.8 KiB) TX errors 0 dropped 29 overruns 0 carrier 0 collisions 0 ステップ 5：docker 設定ファイルの変更 flannel が生成したサブネット環境変数を確認します： 1 [root@web01 ~]# cat /run/flannel/subnet.env 出力例：\n1 2 3 4 FLANNEL_NETWORK=172.16.0.0/16 FLANNEL_SUBNET=172.16.5.1/24 FLANNEL_MTU=1450 FLANNEL_IPMASQ=true 1 [root@web01 ~]# cat /run/docker_opts.env 出力例：\n1 2 3 4 DOCKER_OPT_BIP=\u0026#34;--bip=172.16.5.1/24\u0026#34; DOCKER_OPT_IPMASQ=\u0026#34;--ip-masq=false\u0026#34; DOCKER_OPT_MTU=\u0026#34;--mtu=1450\u0026#34; DOCKER_OPTS=\u0026#34; --bip=172.16.5.1/24 --ip-masq=false --mtu=1450\u0026#34; docker サービス設定を変更します： 1 [root@web01 ~]# vim /usr/lib/systemd/system/docker.service [Service] セクションに以下を追加します：\n1 2 3 ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd:// --containerd=/run/containerd/containerd.sock ExecReload=/bin/kill -s HUP $MAINPID EnvironmentFile=-/run/docker_opts.env docker サービスを再起動します： 1 2 [root@web01 ~]# systemctl daemon-reload [root@web01 ~]# systemctl restart docker.service ステップ 6：docker ネットワークの確認 nginx コンテナを作成して進入します： 1 2 3 4 5 6 7 8 9 [root@web01 ~]# ifconfig docker0: flags=4163\u0026lt;UP,BROADCAST,RUNNING,MULTICAST\u0026gt; mtu 1450 inet 172.16.5.1 netmask 255.255.255.0 broadcast 172.16.5.255 inet6 fe80::42:f6ff:fe5d:5423 prefixlen 64 scopeid 0x20\u0026lt;link\u0026gt; ether 02:42:f6:5d:54:23 txqueuelen 0 (Ethernet) RX packets 10073 bytes 407167 (397.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 48185 bytes 38083646 (36.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 1 2 [root@web01 ~]# docker run -d -p 8800:80 nginx [root@web01 ~]# docker exec -it \u0026lt;コンテナID\u0026gt; /bin/bash コンテナ IP を確認します（例：172.16.5.3）： 1 2 root@コンテナID:/# ifconfig eth0: inet 172.16.5.3 netmask 255.255.255.0 四、web02 ホストの設定（Host2: 192.168.0.208） ステップの説明 設定手順は web01 と完全に同じです。以下のパラメータのみ変更してください： --iface=192.168.8.99（本機の IP） docker コンテナ IP の例：172.16.5.2（flannel が自動割り当て） 五、実験の検証 web01 のコンテナから web02 のコンテナ IP（例：172.16.9.2）に ping を実行します：\nweb02 でコンテナを作成し、コンテナ IP アドレスを確認します\n結果：コンテナ間通信が成功し、flannel ネットワークの設定が完了しました。\n付録：etcd ネットワーク設定の確認 1 2 3 [root@docker-network ~]# etcdctl --endpoints=http://127.0.0.1:2379 get /coreos.com/network/config /coreos.com/network/config {\u0026#34;Network\u0026#34;: \u0026#34;172.16.0.0/16\u0026#34;, \u0026#34;SubnetLen\u0026#34;: 24, \u0026#34;SubnetMin\u0026#34;: \u0026#34;172.16.1.0\u0026#34;,\u0026#34;SubnetMax\u0026#34;: \u0026#34;172.16.10.0\u0026#34;, \u0026#34;Backend\u0026#34;: {\u0026#34;Type\u0026#34;: \u0026#34;vxlan\u0026#34;}} 1 2 3 [root@docker-network ~]# etcdctl --endpoints=http://127.0.0.1:2379 get /coreos.com/network/subnets --prefix --keys-only /coreos.com/network/subnets/172.16.5.0-24 /coreos.com/network/subnets/172.16.9.0-24 1 2 3 [root@docker-network ~]# etcdctl --endpoints=http://127.0.0.1:2379 get /coreos.com/network/subnets/172.16.5.0-24 /coreos.com/network/subnets/172.16.5.0-24 {\u0026#34;PublicIP\u0026#34;:\u0026#34;192.168.8.188\u0026#34;,\u0026#34;PublicIPv6\u0026#34;:null,\u0026#34;BackendType\u0026#34;:\u0026#34;vxlan\u0026#34;,\u0026#34;BackendData\u0026#34;:{\u0026#34;VNI\u0026#34;:1,\u0026#34;VtepMAC\u0026#34;:\u0026#34;5a:67:18:61:6a:5d\u0026#34;}} ","date":"2025-05-21","description":"","objectID":"/ja/posts/flannel-network-lab/","readingTime":3,"tags":["flannel","Docker","ネットワーク","etcd"],"title":"flannel 実践：Docker クロスホストコンテナネットワークをゼロから構築","url":"/ja/posts/flannel-network-lab/","wordCount":597},{"content":"Harbor アクティブスタンバイデプロイ 環境準備 OS: CentOS 8.4 64bit\nHarbor バージョン: harbor-offline-installer-v2.11.1.tgz\nDocker Compose: docker-compose-linux-x86_64\n役割 ホスト名 IP アドレス プライマリ Harbor Harbor01 192.168.8.161 スタンバイ Harbor Harbor02 192.168.8.162 Docker ホスト web01 192.168.8.188 HarborはVMwareのオープンソースエンタープライズDockerレジストリプロジェクトで、公式Docker Registryをベースに、管理UI、ロールベースのアクセス制御（RBAC）、AD/LDAP統合、監査ログなどのエンタープライズ機能を追加しています。Harborの各コンポーネントはDockerコンテナとして構築され、Docker Composeを使用してデプロイされます。\nパート1：プライマリHarborデプロイ（HTTPモード、証明書なし） この方法は社内ネットワーク向けで、SSL証明書なしでHTTPで直接Harborにアクセスします。\n1. Dockerインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 # 既存のyumリポジトリファイルを削除 rm -rf /etc/yum.repos.d/* # Alibaba Cloudミラーからyumリポジトリファイルをダウンロード curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo # Docker CEインストール yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Docker起動とブート時自動起動設定 systemctl enable docker.service --now 2. Dockerミラー設定 1 vim /etc/docker/daemon.json 以下の内容を入力：\n1 2 3 4 5 6 { \u0026#34;registry-mirrors\u0026#34;: [ \u0026#34;https://37564ea7e7cc4824a5049fd666807c27.mirror.swr.myhuaweicloud.com\u0026#34; ], \u0026#34;insecure-registries\u0026#34;: [\u0026#34;http://192.168.8.161\u0026#34;] } 1 2 systemctl daemon-reload systemctl restart docker.service 3. Docker ComposeとHarborインストール 1 2 3 4 5 6 7 8 9 10 # docker-composeとharborオフラインパッケージを/dataに配置 ls /data # docker-compose-linux-x86_64 harbor-offline-installer-v2.11.1.tgz # docker-composeインストール cp /data/docker-compose-linux-x86_64 /usr/local/bin/docker-compose chmod a+x /usr/local/bin/docker-compose # harbor展開 tar -zxvf /data/harbor-offline-installer-v2.11.1.tgz -C /usr/local/ 4. Harbor設定変更 1 2 3 cd /usr/local/harbor/ cp harbor.yml.tmpl harbor.yml vim harbor.yml 主要設定を変更：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 hostname: 192.168.8.161 http: port: 80 # httpsセクション全体をコメントアウト（HTTPモードでは証明書不要） #https: # port: 443 # certificate: /your/certificate/path # private_key: /your/private/key/path harbor_admin_password: Harbor12345 data_volume: /images 他の設定はデフォルトのままにします。\n5. インストール実行 1 ./install.sh インストール後、ブラウザで http://192.168.8.161 にアクセスし、admin / Harbor12345でログイン。\n6. ユーザーとプロジェクトの作成 Harbor Web UIでuser1を作成：\nuser1でログイン：\nuser1として新しいプロジェクト（例：openssh）を作成：\n7. イメージのプッシュとプルテスト Dockerホスト（web01）で作業：\n1 2 3 4 5 6 7 8 9 10 11 # Harborにログイン docker login 192.168.8.161 Username: user1 Password: # Login Succeeded # イメージにタグ付け docker tag nginx:latest 192.168.8.161/openssh/nginx:latest # Harborにプッシュ docker push 192.168.8.161/openssh/nginx:latest プッシュ成功後、Harborでイメージを確認：\n1 2 3 # ローカルイメージを削除して再度プル docker image rm -f 192.168.8.161/openssh/nginx:latest docker pull 192.168.8.161/openssh/nginx:latest プル後、Harborにダウンロード回数+1が表示：\nパート2：スタンバイHarborデプロイ スタンバイのデプロイはプライマリと同一で、hostnameをスタンバイのIPに変更するだけです。\n1 vim /usr/local/harbor/harbor.yml 1 hostname: 192.168.8.162 デプロイ後、http://192.168.8.162 にアクセスしてuser2を作成：\nスタンバイHarborにuser2でログイン：\nパート3：アクティブスタンバイレプリケーション設定 1. プライマリにレプリケーションターゲットを作成 プライマリHarborにadminでログインし、管理 → レジストリに移動して新しいターゲットを作成：\nスタンバイ情報を入力：\nエンドポイントURL：http://192.168.8.162 アクセスID / アクセスキー：user2の資格情報 作成成功：\n2. レプリケーションポリシー作成 管理 → レプリケーションに移動して新しいポリシーを作成：\n宛先レジストリ：Harbor02を選択 モード：イベント駆動（または他のモード） 3. 同期結果の確認 Dockerホストからプライマリにさらにイメージをプッシュ：\n1 2 3 4 5 docker tag httpd:2.4 192.168.8.161/openssh/httpd:2.4 docker push 192.168.8.161/openssh/httpd:2.4 docker tag mysql:5.7 192.168.8.161/openssh/mysql:5.7 docker push 192.168.8.161/openssh/mysql:5.7 プライマリイメージを確認：\nスタンバイイメージを確認（自動同期済み）：\nスタンバイにプライマリから同期されたイメージが表示されれば、アクティブスタンバイレプリケーションが成功しています。\n注意：レプリケーション設定前にすでに存在していたイメージは手動で同期する必要があります。\nパート4：HTTPS有効化（自己署名証明書） 本番環境やパブリックネットワークではHTTPSを推奨します。以下は自己署名証明書の完全なワークフローです。\n1. CAとサーバー証明書の生成 Harborサーバーで実行：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 mkdir -p /data/cert \u0026amp;\u0026amp; cd /data/cert # CA秘密鍵生成 openssl genrsa -out ca.key 4096 # CA証明書生成（10年有効） openssl req -x509 -new -nodes -sha512 -days 3650 \\ -subj \u0026#34;/C=CN/CN=HarborRootCA\u0026#34; \\ -key ca.key \\ -out ca.crt # サーバー秘密鍵生成 openssl genrsa -out harbor.key 4096 # サーバー証明書リクエスト生成（CN = Harbor IPまたはドメイン） openssl req -sha512 -new \\ -subj \u0026#34;/C=CN/CN=192.168.8.161\u0026#34; \\ -key harbor.key \\ -out harbor.csr 2. 証明書拡張情報設定 SAN（Subject Alternative Name）を含む v3.ext ファイルを作成：\n1 2 3 4 5 6 7 8 9 10 cat \u0026gt; v3.ext \u0026lt;\u0026lt;-EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] IP.1=192.168.8.161 EOF IP.1 はHarborの実際のアクセスアドレスと一致する必要があります。一致しない場合、Dockerクライアントが証明書ドメイン不一致エラーを報告します。\n3. サーバー証明書に署名 1 2 3 4 5 openssl x509 -req -sha512 -days 3650 \\ -extfile v3.ext \\ -CA ca.crt -CAkey ca.key -CAcreateserial \\ -in harbor.csr \\ -out harbor.crt 4. Harbor設定でHTTPS有効化 1 vim /usr/local/harbor/harbor.yml httpsセクションのコメントを外し、証明書パスを更新：\n1 2 3 4 5 6 hostname: 192.168.8.161 https: port: 443 certificate: /data/cert/harbor.crt private_key: /data/cert/harbor.key hostnameは v3.ext の IP.1 と一致する必要があります。\n5. Harbor再デプロイ 1 2 3 4 cd /usr/local/harbor/ docker-compose down ./prepare docker-compose up -d 注意：docker-compose down -v を使用しないでください。-v は名前付きボリュームを削除し、Harborデータベースとユーザーデータが失われます。\nデプロイ後、https://192.168.8.161 でアクセス。\n6. Dockerクライアントの証明書信頼設定 イメージのプッシュ/プルが必要なすべてのマシンで実行：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 証明書ディレクトリ作成（名前はHarbor IPまたはドメイン） mkdir -p /etc/docker/certs.d/192.168.8.161 # CA証明書をそのディレクトリにコピー # 方法1：Harborサーバーからscp scp root@192.168.8.161:/data/cert/ca.crt /etc/docker/certs.d/192.168.8.161/ # 方法2：手動でca.crtファイルの内容をコピー # Docker再起動 systemctl restart docker # ログインテスト docker login 192.168.8.161 # adminとパスワードを入力、\u0026#34;Login Succeeded\u0026#34;が表示されれば成功 パート5：FAQ Q：HTTPモードとHTTPSモードを切り替えられますか？\nはい。harbor.yml のhttpsセクションを変更後、./install.sh を再実行してください。HTTPからHTTPSへの切り替えには証明書の事前生成が必要です。HTTPSからHTTPへの切り替えにはhttpsセクションをコメントアウトしてください。\nQ：DockerクライアントがHTTPS Harborへのログイン時に「x509: certificate relies on legacy Common Name field」エラーを報告する場合\n証明書にSAN（Subject Alternative Name）が含まれていないためです。v3.ext に IP.1=\u0026lt;Harbor IP\u0026gt; が含まれており、-extfile v3.ext で署名していることを確認してください。\nQ：レプリケーション失敗のトラブルシューティング方法は？\nプライマリとスタンバイ間のネットワーク接続、ターゲットレジストリの資格情報、対象ユーザーのターゲットプロジェクトへの書き込み権限を確認してください。\n","permalink":"https://LMDAWN1127.github.io/ja/posts/harbor-master-slave/","summary":"HarborエンタープライズDockerレジストリのアクティブスタンバイアーキテクチャ、HTTP/HTTPSモード、自己署名証明書、クロスホストレプリケーションを完全にカバーするデプロイガイドです。","title":"Harbor アクティブスタンバイデプロイ：インストールからHTTPS・レプリケーションまで"},{"content":"一、OpenStack のコアコンポーネントとその役割 1. HORIZON —— 統一グラフィカル管理コンソールサービス コア機能: Web ベースの Dashboard グラフィカル管理コンソールを提供し、クラウド管理者と一般テナントがクラウドリソースを視覚的に割り当て・監視できるようにする。 2. NOVA —— コンピュートリソース管理サービス コア機能: クラウド環境の仮想化コンピュートリソース（nova-compute）を管理・設定する。 役割分担: Controller 制御ノード: nova-api、nova-scheduler、nova-conductor などのスケジューリングサービスを実行する。ユーザーがクラウドインスタンス作成を要求すると、nova-api が要求を受け取り解析し、nova-scheduler がポリシーに基づき最適なコンピュートノードを選択して負荷を分散する。 Compute コンピュートノード: クラウドインスタンスを実際に実行するワーカーノード（KVM、VMware ESXi、Xen などの異種ハイパーバイザーに対応）。 制御ノードの高可用性とパフォーマンスのボトルネック: 制御ノードはすべての API ゲートウェイ、データベース、メッセージキューを担っており、高可用性とパフォーマンスの負荷が生じる。 3. GLANCE —— イメージサービス コア機能: OS イメージの発見・登録・検索・ストレージ管理を担当する。 一般的なディスクイメージ形式: KVM で一般的な形式: qcow2（シンプロビジョニングとコピーオンライト COW をサポート）; VMware で一般的な形式: vmdk。 デプロイ推奨: 通常、高可用性を実現するために制御ノード上に統合・併置してデプロイする。 4. SWIFT —— オブジェクトストレージサービス コア機能: 高可用性・分散・結果整合性のあるオブジェクトストレージサービス（Object Storage）を提供し、静的で非構造化のデータ、クラウドインスタンスのシステムイメージ、データのフルバックアップなどに特化している。 5. NEUTRON —— ソフトウェア定義ネットワーク（SDN） コア機能: クラウド環境でネットワーク・アズ・ア・サービスを提供し、仮想ルーター、スイッチ、セキュリティグループ、フローティング IP、ノード間トラフィックの接続を管理する。 ネットワーク技術: VLAN、VXLAN、Geneve、分散仮想ルーティング（DVR）を全面サポート; ハードウェア SDN モード: 本番環境では通常 2 台の専用ネットワークノードを配置してアクティブ・アクティブまたはアクティブ・スタンバイクラスタを構築する。 6. CINDER —— ブロックストレージサービス コア機能: クラウドインスタンス向けの永続的なブロックストレージ（クラウドディスク）を提供し、動的なアタッチ・デタッチ・スナップショット・容量拡張が可能。 バックエンド連携能力: 従来型ストレージアレイとの連携: Huawei OceanStor、IBM、EMC などのハイエンドハードウェアストレージ; オープンソース分散ストレージとの連携: Ceph RBD、GlusterFS など。 バックエンドの仕組み: ユーザーがクラウドディスクを申請すると、Cinder は指示をバックエンドストレージシステムに下位伝達し、本質的に物理／分散ストレージ内に LUN を切り出してマッピングする。 比較説明: オブジェクトストレージ（Baidu Netdisk、Swift、S3 など）はブロックデバイスとして直接フォーマットしてクラウドインスタンスのファイルシステムとしてマウントできないが、Cinder ブロックデバイスは直接フォーマットしてマウントして利用できる。 7. HEAT —— オーケストレーションサービス コア機能: 宣言型テンプレート（HOT テンプレートまたは AWS CloudFormation 形式）に基づき、グラフィカルなオーケストレーションやスクリプトで複数の VM、データベースクラスタ、ネットワークトポロジ、監視ポリシーをワンクリックで自動一括デプロイする。 8. CEILOMETER —— メータリング・監視サービス コア機能: 物理リソースと仮想リソースのパフォーマンス指標、稼働時間、使用量を収集する。 パブリッククラウドシナリオ: API 呼び出し回数、ネットワーク送信量、コンピュート時間を記録し、課金システムと連携する; プライベートクラウドシナリ오: テナントのクォータ水位を監視し、リソースの過剰利用や遊休を特定してキャパシティプランニングを支援する。 9. KEYSTONE —— 統一認証・認可サービス コア機能: OpenStack 全体のセキュリティの礎石であり、プラットフォーム全体のテナント（Project）、ユーザー（User）、ロール（Role）、サービスカタログ、トークン認証を担当する。 エンタープライズ向けアイデンティティフェデレーション: 企業の既存の Windows Active Directory (AD) や Linux OpenLDAP とシームレスに統合し、エンタープライズグレードの統一アカウント単一サインオン（SSO）を実現する; フロー承認と権限分離（Huawei Cloud の例）: クラウドインスタンスの多段階申請・承認ワークフローをサポート（最大 5 段階の承認）; 「三権分立」のセキュリティ原則を徹底（セキュリティ責任者、システム管理者、監査員が権限を分離して管理）; 顧客の自社開発 OA/BPM 承認フローシステムとの連携をサポート。 コアコンポーネント早見表： コンポーネント名 コード名 コアサービス機能 Horizon Dashboard 統一 Web グラフィカル管理コンソール Nova Compute コンピュートリソースのライフサイクルとインスタンススケジューリング管理 Glance Image 仮想マシンイメージのストレージとバージョン登録 Swift Object 大規模非構造化オブジェクトストレージサービス Neutron Network ソフトウェア定義ネットワーク（SDN）、ルーティングとセキュリティグループ管理 Cinder Block クラウドインスタンスの永続ブロックストレージ（クラウドディスク）管理 Heat Orchestration インフラストラクチャ・アズ・コード（IaC）の複数リソーススタックオーケストレーション Ceilometer Metering リソース使用量統計、監視メータリング、クォータ分析 Keystone Identity 統一認証、認可トークン、サービスカタログ管理 二、OpenStack デプロイ計画（Victoria 版） 1. デプロイ方式の比較 オープンソースの手動デプロイ: コンポーネントを個別にコンパイル・設定する—煩雑で複雑であり、通常は基盤メカニズムの深い学習向け; ツールによる自動化デプロイ: Ansible デプロイ（OpenStack-Ansible、Kolla-Ansible など）; Packstack デプロイ: Red Hat が公開する Puppet ベースの自動化迅速デリバリーツール（本実践で採用）; 2. クラスタノード仕様とネットワーク計画 （1）Controller 制御ノード（1 台） 搭載コンポーネント: API サービス: nova-api、cinder-api、glance-api、neutron-server など; 基盤サービス: MariaDB / MySQL、RabbitMQ メッセージキュー、Memcached、Keystone; ネットワーク・管理サービス: ネットワークノードの外部ルーティング転送、ローカル YUM キャッシュ、Chrony 時刻同期サーバー。 システム構成要件: CPU: 4 vCPU 以上 メモリ: 4GB 以上 ディスク: 100GB の空きディスク容量 NIC: 3 枚のネットワークカード（NIC 1 はインターネット接続用ブリッジモード、NIC 2 と NIC 3 はホストオンリー mode で内部トラフィック） IP アドレス計画: 内部管理 IP: 192.168.100.10 外部アクセス IP: 192.168.10.10 （2）Compute コンピュートノード（1 台） 搭載コンポーネント: nova-compute、ネットワーク L2 Agent（Open vSwitch Agent） システム構成要件: CPU: 4 vCPU 以上 メモリ: 8GB 以上（最低 4GB） ディスク: 100GB のディスク容量 NIC: 3 枚のネットワークカード（すべてホストオンリー mode） IP アドレス計画: Compute: 192.168.100.11 （3）YUM リポジトリサーバー + Chrony 時刻同期サーバー（1 台） システム構成要件: CPU: 2 vCPU メモリ: 2GB NIC: 2 枚（1 枚はインターネットにブリッジして公開時刻同期と上流リポジトリ用、もう 1 枚はホストオンリーで内部ノードへ提供） IP アドレス計画: 外部 IP: 192.168.10.11 内部 IP: 192.168.100.20 環境ダウングレード説明: パーソナルコンピュータのハードウェア資源が限られている場合、最小構成を 2 台の VM に圧縮できる（制御ノードを YUM ソースと時刻同期サーバーとして兼用し、もう 1 台をコンピュートノードとする）。注意: 各ノードのシステム時刻は高度に一致していなければならず、時刻ドリフトは 5 分を超えてはならない。さもないと Keystone ハンドシェイクとメッセージキュー通信が全面的に失敗する。\n三、OpenStack 自動化デプロイ実践手順 フェーズ1：YUM リポジトリサーバーと Chrony 時刻同期サーバーの構築 1. ネットワークインターフェースの設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 # 1. 内部通信用 NIC ens160 を設定 [root@Cloud ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens160 TYPE=Ethernet BOOTPROTO=none NAME=ens160 DEVICE=ens160 ONBOOT=yes IPADDR=192.168.100.20 PREFIX=24 # 2. インターネット接続用 NIC ens192 を設定（公開 NTP 同期用） [root@Cloud ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens192 TYPE=Ethernet BOOTPROTO=none NAME=ens192 DEVICE=ens192 ONBOOT=yes PROXY_METHOD=none BROWSER_ONLY=no IPADDR=192.168.10.11 PREFIX=24 GATEWAY=192.168.10.1 DNS1=192.168.10.1 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=no UUID=03da7500-2101-c722-2438-d0d006c28c73 # NIC を再起動して設定を有効化 [root@Cloud ~]# nmcli connection down ens160 ; nmcli connection up ens160 Connection \u0026#39;ens160\u0026#39; successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1) Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4) [root@Cloud ~]# nmcli connection down ens192 ; nmcli connection up ens192 Connection \u0026#39;ens192\u0026#39; successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3) Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/5) 2. ローカル CD-ROM YUM リポジトリの設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@Cloud ~]# cd /etc/yum.repos.d/ [root@Cloud yum.repos.d]# mkdir bak [root@Cloud yum.repos.d]# mv CentOS-Linux-* bak/ # OS インストール ISO をマウント mount /dev/cdrom /media/ # CD-ROM ローカルリポジトリ設定ファイルを作成 [root@Cloud ~]# cat \u0026gt; /etc/yum.repos.d/dvd.repo \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; \u0026gt; [BaseOS] \u0026gt; name=BaseOS \u0026gt; baseurl=file:///media/BaseOS \u0026gt; gpgcheck=0 \u0026gt; \u0026gt; [AppStream] \u0026gt; name=AppStream \u0026gt; baseurl=file:///media/AppStream \u0026gt; gpgcheck=0 \u0026gt; EOF 3. Chrony 時刻同期サーバーの設定 OpenStack はノード間の時刻同期に対する要求が極めて厳しいため、まず時刻ソースを設定する:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # /etc/chrony.conf を編集 [root@Cloud ~]# vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). pool ntp.tencent.com iburst # Allow NTP client access from local network. allow 192.168.100.0/24 # Serve time even if not synchronized to a time source. local stratum 10 # 時刻同期サービスを再起動して検証 [root@Cloud ~]# systemctl restart chronyd.service [root@Cloud ~]# chronyc sources 210 Number of sources = 1 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 106.55.184.199 2 6 17 2 -224us[ -144us] +/- 54ms # ファイアウォールと SELinux を無効化 [root@Cloud ~]# systemctl disable firewalld.service --now [root@Cloud ~]# setenforce 0 [root@Cloud ~]# sed -i \u0026#39;s/^SELINUX=.*/SELINUX=disabled/\u0026#39; /etc/selinux/config 4. httpd によるローカル Web YUM リポジトリの構築 CentOS 8 および OpenStack Victoria ソフトウェアリポジトリを HTTP ミラーソースとして公開し、すべてのクラスタノードが取得できるようにする。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 # 1. Apache Web サービスをインストールして起動 [root@Cloud ~]# yum -y install httpd [root@Cloud ~]# systemctl enable httpd --now # 2. ディレクトリを作成しイメージファイルをマウント [root@Cloud ~]# mkdir /isos [root@Cloud ~]# mkdir -p /var/www/html/centos8 [root@Cloud ~]# mkdir -p /var/www/html/openstack # ベースシステム CD と OpenStack Victoria インストールイメージをマウント [root@Cloud ~]# mount /dev/cdrom /var/www/html/centos8/ [root@Cloud ~]# mount /isos/26-CentOS8-4-OSP-Victoria.iso /var/www/html/openstack/ # 3. マウントを /etc/fstab に永続化 [root@Cloud ~]# vim /etc/fstab /dev/cdrom /var/www/html/centos8 iso9660 defaults 0 0 /isos/26-CentOS8-4-OSP-Victoria.iso /var/www/html/openstack iso9660 defaults 0 0 # 4. HTTP YUM リポジトリファイルを設定 [root@Cloud ~]# vim /etc/yum.repos.d/dvd.repo [BaseOS] name=BaseOS baseurl=http://192.168.100.20/centos8/BaseOS gpgcheck=0 [AppStream] name=AppStream baseurl=http://192.168.100.20/centos8/AppStream gpgcheck=0 [root@Cloud ~]# vim /etc/yum.repos.d/openstack.repo [centos-advanced-virtualization] name=centos-advanced-virtualization baseurl=http://192.168.100.20/openstack/centos-advanced-virtualization gpgcheck=0 [centos-nfv-openvswitch] name=centos-nfv-openvswitch baseurl=http://192.168.100.20/openstack/centos-nfv-openvswitch gpgcheck=0 [centos-rabbitmq-38] name=centos-rabbitmq-38 baseurl=http://192.168.100.20/openstack/centos-rabbitmq-38 gpgcheck=0 [PowerTools] name=PowerTools baseurl=http://192.168.100.20/openstack/PowerTools gpgcheck=0 [centos-ceph-nautilus] name=centos-ceph-nautilus baseurl=http://192.168.100.20/openstack/centos-ceph-nautilus gpgcheck=0 [centos-openstack-victoria] name=centos-openstack-victoria baseurl=http://192.168.100.20/openstack/centos-openstack-victoria gpgcheck=0 [extras] name=extras baseurl=http://192.168.100.20/openstack/extras gpgcheck=0 # 5. 作成した repo ファイルを各制御ノードとコンピュートノードに一括配布 [root@Cloud ~]# scp /etc/yum.repos.d/dvd.repo /etc/yum.repos.d/openstack.repo root@192.168.100.10:/etc/yum.repos.d/ [root@Cloud ~]# scp /etc/yum.repos.d/dvd.repo /etc/yum.repos.d/openstack.repo root@192.168.100.11:/etc/yum.repos.d/ フェーズ2：各クラスタノードのシステム環境初期化 1. Controller 制御ノードの初期化（192.168.100.10） 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 # 1. 管理ネットワーク ens160 を設定 [root@Controller ~]# nmcli connection modify ens160 ipv4.addresses 192.168.100.10/24 ipv4.method manual autoconnect yes [root@Controller ~]# nmcli connection down ens160 ; nmcli connection up ens160 # 2. 外部ネットワーク NIC ens224 を設定 [root@Controller ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens224 TYPE=Ethernet BOOTPROTO=none NAME=ens224 DEVICE=ens224 ONBOOT=yes [root@Controller ~]# nmcli connection reload [root@Controller ~]# nmcli connection modify ens224 ipv4.addresses 192.168.10.10/24 ipv4.gateway 192.168.10.1 ipv4.dns 192.168.10.1 ipv4.method manual autoconnect yes [root@Controller ~]# nmcli connection down ens224 ; nmcli connection up ens224 # 3. Chrony NTP クライアントを設定 [root@Controller ~]# vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). pool 192.168.100.20 iburst [root@Controller ~]# systemctl restart chronyd.service [root@Controller ~]# chronyc sources 210 Number of sources = 1 MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^* 192.168.100.20 3 6 377 24 -22us[ -46us] +/- 43ms # 4. ホスト名を設定 [root@Controller ~]# hostnamectl set-hostname Controller # 5. ファイアウォールと SELinux を無効化 [root@Controller ~]# systemctl disable firewalld.service --now [root@Controller ~]# setenforce 0 [root@Controller ~]# sed -i \u0026#39;s/^SELINUX=.*/SELINUX=disabled/\u0026#39; /etc/selinux/config # 6. クラスタの /etc/hosts 名前解決を設定 [root@Controller ~]# vim /etc/hosts 192.168.100.10 Controller 192.168.100.11 Compute # 7. デフォルトシステム repo キャッシュを削除 [root@Controller ~]# cd /etc/yum.repos.d [root@Controller yum.repos.d]# mkdir -p bak \u0026amp;\u0026amp; mv CentOS-Linux-* bak/ 2. Compute コンピュートノードの初期化（192.168.100.11） 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 1. 管理ネットワークを設定 [root@Compute ~]# nmcli connection modify ens160 ipv4.addresses 192.168.100.11/24 ipv4.method manual autoconnect yes [root@Compute ~]# nmcli connection down ens160 ; nmcli connection up ens160 # 2. Chrony NTP クライアントを設定 [root@Compute ~]# vim /etc/chrony.conf # Use public servers from the pool.ntp.org project. # Please consider joining the pool (http://www.pool.ntp.org/join.html). pool 192.168.100.20 iburst [root@Compute ~]# systemctl enable chronyd.service --now # 3. ホスト名を設定 [root@Compute ~]# hostnamectl set-hostname Compute # 4. ファイアウォールと SELinux を無効化 [root@Compute ~]# systemctl disable firewalld.service --now [root@Compute ~]# setenforce 0 [root@Compute ~]# sed -i \u0026#39;s/^SELINUX=.*/SELINUX=disabled/\u0026#39; /etc/selinux/config # 5. クラスタ hosts 名前解決を設定 [root@Compute ~]# vim /etc/hosts 192.168.100.10 Controller 192.168.100.11 Compute # 6. デフォルトシステム repo を削除 [root@Compute ~]# cd /etc/yum.repos.d [root@Compute yum.repos.d]# mkdir -p bak \u0026amp;\u0026amp; mv CentOS-Linux-* bak/ ⚠️ 重要チェックポイント: この時点で全 VM をシャットダウンし、異常発生時に迅速にロールバックできるよう統一スナップショットを取得することを推奨。\nフェーズ3：Packstack 自動化アンサーファイルデプロイ 1. Packstack デプロイツールのインストール 制御ノード（Controller）で実行:\n1 [root@Controller ~]# yum -y install openstack-packstack 2. デフォルトのアンサーファイルを生成 1 [root@Controller ~]# packstack --gen-answer-file=/root/answers.txt ネットワーク方式の説明: OpenStack Victoria は OVN（Open Virtual Network）と従来の OVS（Open vSwitch）の両方をサポートする。\n3. アンサーファイルのパラメータを精密にカスタマイズ 1 2 # 自動検出された外部 IP を内部管理 IP 192.168.100.10 に統一置換 [root@Controller ~]# sed -i \u0026#39;s/192.168.10.10/192.168.100.10/g\u0026#39; /root/answers.txt /root/answers.txt を編集し、以下のコア設定項目を確認・修正する:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 # 1. コンピュートノードクラスタの IP 一覧を指定（カンマ区切り） CONFIG_COMPUTE_HOSTS=192.168.100.11 # 2. Keystone 管理者 root の初期パスワードを設定 CONFIG_KEYSTONE_ADMIN_PW=000000 # 3. Demo テナントネットワークを無効化（本番化規範） CONFIG_PROVISION_DEMO=n # 4. Heat オーケストレーションコンポーネントを有効化 CONFIG_HEAT_INSTALL=y # 5. Neutron コアドライバーとネットワークタイプ設定（ML2 + OVS） CONFIG_NEUTRON_ML2_TYPE_DRIVERS=geneve,flat,vxlan,vlan CONFIG_NEUTRON_ML2_MECHANISM_DRIVERS=openvswitch CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES=vxlan CONFIG_NEUTRON_L2_AGENT=openvswitch # 6. OVS 外部ネットワークブリッジバインディング設定（物理外部 NIC ens224 を関連付け） CONFIG_NEUTRON_OVS_BRIDGE_MAPPINGS=extnet:br-ex CONFIG_NEUTRON_OVS_BRIDGE_IFACES=br-ex:ens224 # 7. ストレージクォータ容量を事前設定 CONFIG_SWIFT_STORAGE_SIZE=20G CONFIG_CINDER_VOLUMES_SIZE=50G ⚠️ 重要チェックポイント: アンサーファイル修正後、再度すべての VM をシャットダウンしてスナップショットを取得することを推奨。\n4. ワンクリック自動化デプロイの実行 電源投入後、制御ノードでデプロイコマンドを実行:\n1 [root@Controller ~]# packstack --answer-file=/root/answers.txt デプロイスクリプトは Puppet に基づき、全ノードでソフトウェアソース設定、データベースのテーブル作成、メッセージキュークラスタ構築、証明書生成、各コンポーネントの協調統合テストを自動で完了する。終了後、ターミナルに Dashboard ログイン URL と keystonerc_admin 環境変数ファイルのパスを出力する。\n四、Linux システムログ管理と OpenStack トラブルシューティング 1. Linux Rsyslog のログレベルと設定アーキテクチャ Linux システムでは、システムの低層と大部分のサービスのログは rsyslog デーモンによって集中管理される。\n設定ファイルを確認: 1 2 rpm -qc rsyslog # コアのメイン設定ファイル: /etc/rsyslog.conf ログルールの構文解析： 1 サービス種別(Facility).ログレベル(Priority) ログ格納パス 一般的な設定例:\n1 2 3 4 5 6 7 8 9 # 1. システム共通の通常メッセージ: # すべてのサービスの \u0026gt;=info レベルのログを記録するが、メール・認証セキュリティ・ cron ログを除外 *.info;mail.none;authpriv.none;cron.none /var/log/messages # 2. デバッグログ: *.debug /var/log/debug # 3. エラーレベルログ: *.err /var/log/error.log 構文ルールの要点: mail: サービス種別（Facility）; info: ログ優先度レベル; .: 以上（\u0026gt;=） の優先度のログメッセージに一致することを示す; *.info: すべてのサービスの \u0026gt;= info レベルのログが対象ファイルに集約されて書き込まれることを意味する。 リアルタイム動的ログ監視コマンド： 1 2 3 4 5 # システムログの末尾出力を追跡 tail /var/log/messages # リアルタイムでログストリームを継続監視 tail -f /var/log/messages 2. OpenStack カスタムサービスログのトラブルシューティング基準 トラブルシューティング原則: 各コンポーネントは通常独自のカスタムログファイル体系（/var/log/\u0026lt;コンポーネント名\u0026gt;/ 配下）を持つ。コンポーネントが異常の場合、まずそのコンポーネント専用ログを排查し、カスタムログがない場合のみシステム全体ログ /var/log/messages に戻って排查する。\n実践例：Neutron ネットワークサービスの障害特定 デプロイまたは運用中に、仮想ネットワーク作成が失敗したり OVS ポートが起動しなかったりする場合、正規表現マッチングでエラーと警告を直接捕捉できる:\n1 2 3 4 5 # 1. 全 Neutron ログから正規表現でエラーと警告を横断フィルタ tail -f /var/log/neutron/*.log | grep -iE \u0026#39;(err|warn)\u0026#39; # 2. neutron-server コア API サービスログを深く排查し、マッチ項目の前後 3 行のコンテキストを出力: tail -f /var/log/neutron/server.log | grep -iE -A3 -B3 \u0026#39;(err|warn)\u0026#39; パラメータ説明:\n-i: 大文字小文字を無視; -E: 拡張正規表現マッチング (err|warn) を有効化; -A 3 (After): マッチ行の後 3 行を出力; -B 3 (Before): マッチ行の前 3 行を出力。 ","permalink":"https://LMDAWN1127.github.io/ja/posts/openstack-core-architecture-deployment/","summary":"コアコンポーネント（Nova/Glance/Neutron/Cinder など）から、Packstack を用いた Victoria リリースの一元自動デプロイ、さらに Rsyslog ログトラブルシューティングまで。","title":"OpenStack クラウド OS：コアアーキテクチャと自動化デプロイ"},{"content":"Cinder のボリューム作成とアタッチの構成 ボリューム作成の流れは cinder ノード（コントローラーノード）が提供し、ボリュームのマウントは nova が提供します\nローカル LVM + iSCSI ボリュームストレージの設定 answers.txt 応答ファイルで cinder ボリュームを作成するよう指定します。実験環境では専用のストレージ機器を用意できないため、システムはローカル LVM を cinder ストレージとして採用します システムは既定で cinder-volumes ボリュームグループを 50G で作成します（ユーザーが手動で指定）\nこのボリュームグループはコントローラーノード上に作成されます\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [root@Controller ~]# vgdisplay --- Volume group --- VG Name cl System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 3 Open LV 3 Max PV 0 Cur PV 1 Act PV 1 VG Size \u0026lt;99.00 GiB PE Size 4.00 MiB Total PE 25343 Alloc PE / Size 25343 / \u0026lt;99.00 GiB Free PE / Size 0 / 0 VG UUID K2c9TX-MlXI-k9Ga-CPPm-3zuu-WNoK-mRuUEZ --- Volume group --- VG Name cinder-volumes System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 0 Max PV 0 Cur PV 1 Act PV 1 VG Size \u0026lt;51.50 GiB PE Size 4.00 MiB Total PE 13183 Alloc PE / Size 12551 / \u0026lt;49.03 GiB Free PE / Size 632 / \u0026lt;2.47 GiB VG UUID nXhaeU-1PwG-is18-Ef2N-cK5R-9LRk-3ksn1k /etc/cinder/cinder.conf で LVM ドライバを呼び出し、作成したボリュームグループを認識させます このコントローラーノードを ISCSI ストレージ（target）とみなし、ユーザーが作成したボリュームを ISCSI で compute ノードに共有します ユーザーが 2G のクラウドディスクを作成すると、システムは自動的に LVM ドライバを呼び出してボリュームグループ内に 2G の LV を作成します\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 [root@Controller ~]# lvdisplay --- Logical volume --- LV Path /dev/cl/swap LV Name swap VG Name cl LV UUID f9Aqve-GgxT-gQNg-v0W0-ogyz-1cJT-WIEOMw LV Write Access read/write LV Creation host, time localhost.localdomain, 2026-06-27 05:28:10 +0800 LV Status available # open 2 LV Size \u0026lt;7.88 GiB Current LE 2016 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:1 --- Logical volume --- LV Path /dev/cl/home LV Name home VG Name cl LV UUID 5f8ntZ-4pxS-yYFl-3BHC-qKaW-pFsi-2ZGkHg LV Write Access read/write LV Creation host, time localhost.localdomain, 2026-06-27 05:28:10 +0800 LV Status available # open 1 LV Size 29.89 GiB Current LE 7653 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:2 --- Logical volume --- LV Path /dev/cl/root LV Name root VG Name cl LV UUID 32JpBQ-Ld4z-0bLU-jHuG-iMRC-WLoO-WtcrnT LV Write Access read/write LV Creation host, time localhost.localdomain, 2026-06-27 05:28:10 +0800 LV Status available # open 1 LV Size \u0026lt;61.23 GiB Current LE 15674 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:0 --- Logical volume --- LV Name cinder-volumes-pool VG Name cinder-volumes LV UUID ughXDw-Fl7B-Mbo9-vsHS-OvMy-Pi60-E2GPaa LV Write Access read/write (activated read only) LV Creation host, time Controller, 2026-07-08 16:03:29 +0800 LV Pool metadata cinder-volumes-pool_tmeta LV Pool data cinder-volumes-pool_tdata LV Status available # open 0 LV Size \u0026lt;48.93 GiB Allocated pool data 0.00% Allocated metadata 10.44% Current LE 12525 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:6 --- Logical volume --- LV Path /dev/cinder-volumes/volume-3561d822-2929-4b47-87c5-25f769f8f44e LV Name volume-3561d822-2929-4b47-87c5-25f769f8f44e VG Name cinder-volumes LV UUID WoSBug-zWc4-wVYn-39xk-MWVw-z3Pj-UOdvok LV Write Access read/write LV Creation host, time Controller, 2026-10-05 15:56:30 +0800 LV Pool name cinder-volumes-pool LV Status available # open 0 LV Size 2.00 GiB Mapped size 0.00% Current LE 512 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 8192 Block device 253:7 ユーザーがこのボリュームをクラウドサーバー web01 にアタッチすると、cinder はストレージ側に指示を送ります。ストレージ側はその LV を compute ホストに共有し、compute ホストがそのディスクを認識して新しい 2G ディスクが生まれ、libvirt が xml ファイルを呼び出してクラウドサーバーに追加します\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [root@Controller ~]# systemctl status target ● target.service - Restore LIO kernel target configuration Loaded: loaded (/usr/lib/systemd/system/target.service; enabled; vendor preset: disabled) Active: active (exited) since Mon 2026-10-05 14:18:51 CST; 1h 30min ago Process: 1873 ExecStart=/usr/bin/targetctl restore (code=exited, status=0/SUCCESS) Main PID: 1873 (code=exited, status=0/SUCCESS) Tasks: 0 (limit: 36406) Memory: 0B CGroup: /system.slice/target.service Oct 05 14:18:50 Controller systemd[1]: Starting Restore LIO kernel target configuration... Oct 05 14:18:51 Controller target[1873]: No saved config file at /etc/target/saveconfig.json, ok, exiting Oct 05 14:18:51 Controller systemd[1]: Started Restore LIO kernel target configuration. [root@Controller ~]# targetcli targetcli shell version 2.1.53 Copyright 2011-2013 by Datera, Inc and others. For help on commands, type \u0026#39;help\u0026#39;. /\u0026gt; ls o- / ......................................................................................................................... [...] o- backstores .............................................................................................................. [...] | o- block .................................................................................................. [Storage Objects: 1] | | o- iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e [/dev/cinder-volumes/volume-3561d822-2929-4b47-87c5-25f769f8f44e (2.0GiB) write-thru activated] | | o- alua ................................................................................................... [ALUA Groups: 1] | | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized] | o- fileio ................................................................................................. [Storage Objects: 0] | o- pscsi .................................................................................................. [Storage Objects: 0] | o- ramdisk ................................................................................................ [Storage Objects: 0] o- iscsi ............................................................................................................ [Targets: 1] | o- iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e ............................................. [TPGs: 1] | o- tpg1 .......................................................................................... [no-gen-acls, auth per-acl] | o- acls .......................................................................................................... [ACLs: 1] | | o- iqn.1994-05.com.redhat:1220933cde3c ...................................................... [1-way auth, Mapped LUNs: 1] | | o- mapped_lun0 ................. [lun0 block/iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e (rw)] | o- luns .......................................................................................................... [LUNs: 1] | | o- lun0 [block/iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e (/dev/cinder-volumes/volume-3561d822-2929-4b47-87c5-25f769f8f44e) (default_tg_pt_gp)] | o- portals .................................................................................................... [Portals: 1] | o- 192.168.100.10:3260 .............................................................................................. [OK] o- loopback ......................................................................................................... [Targets: 0] /\u0026gt; [root@Compute ~]# cat /etc/iscsi/initiatorname.iscsi InitiatorName=iqn.1994-05.com.redhat:1220933cde3c [root@Compute ~]# iscsiadm -m session tcp: [1] 192.168.100.10:3260,1 iqn.2010-10.org.openstack:volume-3561d822-2929-4b47-87c5-25f769f8f44e (non-flash) [root@Compute ~]# vim /etc/libvirt/qemu/instance-00000002.xml \u0026lt;disk type=\u0026#39;block\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;raw\u0026#39; cache=\u0026#39;none\u0026#39; io=\u0026#39;native\u0026#39;/\u0026gt; \u0026lt;source dev=\u0026#39;/dev/sda\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vdb\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;serial\u0026gt;3561d822-2929-4b47-87c5-25f769f8f44e\u0026lt;/serial\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x00\u0026#39; slot=\u0026#39;0x07\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; ストレージ側の設定\ntargetcli パッケージをインストールし、サービスを起動します 1 2 3 4 5 6 7 8 9 #yum -y install targetcli #systemctl enable target --now #targetcli /\u0026gt; /backstores/block create dev=/dev/sdb1 name=data01 /\u0026gt; /iscsi create iqn.2024.com.storage:disk /\u0026gt; /iscsi/ iqn.2024.com.storage:disk/tpg1/acls create iqn.1994-05.com.redhat:b4ff583759f4 /\u0026gt;/iscsi/ iqn.2024.com.storage:disk /tpg1/luns create data01 /\u0026gt; /iscsi/ iqn.2024.com.storage:disk/tpg1/portals create 192.168.100.10:3260 /\u0026gt; saveconfig ターゲット、業務サーバー、ストレージクライアント 1 2 3 [root@Compute ~]# iscsiadm -m discovery -t st -p 192.168.100.10 [root@Compute ~]# iscsiadm -m node -T iqn.2024.com.storage:disk -p 192.168.100.10:3260 -l #fdisk -l Cinder と NFS ストレージの連携 上の図に従ってネットワークを設計・設定します\n1. NFS ストレージの設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #配置网络 [root@storage ~]# nmcli connection modify ens160 ipv4.addresses 192.168.200.20/24 ipv4.method manual autoconnect yes [root@storage ~]# nmcli connection down ens160 ; nmcli connection up ens160 [root@storage ~]# cd /etc/sysconfig/network-scripts/ [root@storage network-scripts]# cp ifcfg-ens160 ifcfg-ens192 [root@storage network-scripts]# cat ifcfg-ens192 # Generated by parse-kickstart TYPE=Ethernet DEVICE=ens192 ONBOOT=yes BOOTPROTO=none NAME=ens192 [root@storage ~]# nmcli connection reload [root@storage ~]# nmcli connection modify ens192 ipv4.addresses 192.168.8.20/24 ipv4.method manual autoconnect yes [root@storage ~]# nmcli connection down ens192 ; nmcli connection up ens192 #安装配置安装NFS服务 [root@storage ~]# yum install -y nfs-utils rpcbind [root@storage ~]# mkdir /storage [root@storage ~]# cat /etc/exports /storage 192.168.200.0/24(rw,sync,no_root_squash) /storage 192.168.8.0/24(rw,sync,no_root_squash) [root@storage ~]# systemctl enable nfs-server --now [root@storage ~]# systemctl enable rpcbind --now 2. cinder ノードのネットワーク設定（コントローラーノード） 1 2 3 4 5 6 7 8 [root@Controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens192 TYPE=Ethernet NAME=ens192 DEVICE=ens192 ONBOOT=yes IPADDR=192.168.8.10 NETMASK=255.255.255.0 [root@Controller ~]# systemctl restart network 3. コンピュートノードのネットワーク設定 1 2 [root@Compute ~]# nmcli connection modify ens192 ipv4.addresses 192.168.200.10/24 autoconnect yes ipv4.method manual [root@Compute ~]# nmcli connection down ens192 ; nmcli connection up ens192 4. cinder の設定 1 2 3 4 5 6 7 8 9 10 [root@Controller ~]# vim /etc/cinder/cinder.conf 410 default_volume_type=nfs 436 enabled_backends=lvm,nfs666 [nfs666] volume_backend_name=nfsdata volume_driver=cinder.volume.drivers.nfs.NfsDriver nfs_shares_config = /etc/cinder/nfs_shares [root@Controller ~]# cat /etc/cinder/nfs_shares storage:/storage [root@Controller ~]# systemctl restart openstack-cinder-* Cinder ノード\n1 2 [root@Controller ~]# cat /etc/hosts ####额外增加一条记录 192.168.8.20 storage コンピュートノード\n1 2 3 4 5 6 [root@Compute ~]# cat /etc/hosts 192.168.200.20 storage [root@Controller ~]# source keystonerc_admin [root@Controller ~(keystone_admin)]# cinder type-create nfs [root@Controller ~(keystone_admin)]# cinder type-key nfs set volume_backend_name=nfsdata [root@Controller ~(keystone_admin)]# systemctl restart openstack-cinder-* OpenStack の Web 画面でボリュームを作成し、nfs を選択してそのボリュームをクラウドサーバーに関連付けます\nOpenStack の Web 画面でボリュームを作成し、nfs を選択、ソースにイメージを選びます。クラウドサーバー作成時にはソースとして先ほど作成したボリュームを選択します\nクラウドサーバーを作成し終えると 1 つのボリュームが生成されます\n元のクラウドサーバーを削除して再度作成し直すと、このボリュームが利用できるようになります\n","permalink":"https://LMDAWN1127.github.io/ja/posts/openstack-cinder-block-storage/","summary":"OpenStack Cinder ブロックストレージを整理：ボリューム作成とマウントの役割分担（Cinder が作成、Nova がマウント）、ローカル LVM + iSCSI でコントローラをストレージ化する一連の流れ（VG/LV、targetcli による ISCSI 共有、libvirt でのマウント）、および NFS バックエンド連携とダッシュボード操作。","title":"OpenStack Cinder ブロックストレージ詳細解説：ローカル LVM + iSCSI ボリュームと NFS バックエンド連携"},{"content":"Keystone サービス OpenStack のマルチドメイン対応\n1 2 [root@Controller ~]# vim /etc/openstack-dashboard/local_settings OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True システム内の全サービスを一覧表示\n1 [root@Controller ~(keystone_admin)]# openstack service list Keystone アドレスと API インターフェース\n1 OS_AUTH_URL=http://192.168.100.10:5000/v3 全てのサービスは Keystone のアドレスを知っています。ユーザートークンが有効かを Keystone に検証してもらう必要があるためです Keystone は全てのサービスのアドレスを知っています。全てのサービスは作成時に Keystone へ登録を行うためです エンドポイントアドレス\n1 [root@Controller ~(keystone_admin)]# openstack endpoint list 各サービスには 3 つのエンドポイントアドレスがあり、これら 3 つの URL は同じでも異なっていても構いません\npublic url — 外部ユーザーがアクセスする URL アドレス\nadmin url — 管理者がアクセスする URL アドレス\ninternal url — 内部コンポーネント間でアクセスする URL アドレス\nクラウドサーバー提供の流れ\nユーザーは Keystone にユーザー名とパスワードを送信してリクエストします。認証が成功すると Keystone はトークンを発行し、ユーザーはそのトークンを使って nova-api にクラウドサーバー作成リクエストを送ります nova-api は Keystone に助けを求め、そのトークンが有効かどうかを検証してもらい、成功すれば結果が返されます nova-api はリクエストを nova-compute ホストに送信します nova-compute ホストはユーザーのリクエスト情報に基づいてクラウドサーバーを作成し、結果を nova-api に返します nova-api は結果をユーザーに返します。クラウドサーバーの作成が完了し、そのホスト情報はデータベースに記録されます nova-api にサーバー作成リクエストを送る際、私は nova-api のアドレスを知りません。しかし Keystone のアドレスは知っています。Keystone に nova-api のアドレスを問い合わせます。Keystone は全サービスのエンドポイントアドレスを保持しているため、私は Keystone のアドレスだけ知っていればよいのです。以下は Keystone のアドレスを調べ、そこから他のアドレスを引く方法です。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 [root@Controller ~(keystone_zlm)]# grep -E \u0026#34;^connection\\s*=.*keystone\u0026#34; /etc/keystone/*.conf /etc/keystone/keystone.conf:connection=mysql+pymysql://keystone_admin:c3fa63522e1f4586@192.168.100.10/keystone # 用户名：keystone_admin # 密码：c3fa63522e1f4586 [root@Controller ~(keystone_zlm)]# mysql -u keystone_admin -p -D keystone Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 15494 Server version: 10.3.27-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [keystone]\u0026gt; SELECT s.type AS service_type, -\u0026gt; e.interface, -\u0026gt; e.url -\u0026gt; FROM endpoint e -\u0026gt; JOIN service s ON e.service_id = s.id -\u0026gt; ORDER BY s.type, e.interface; +----------------+-----------+--------------------------------------------------+ | service_type | interface | url | +----------------+-----------+--------------------------------------------------+ | alarming | admin | http://192.168.100.10:8042 | | alarming | internal | http://192.168.100.10:8042 | | alarming | public | http://192.168.100.10:8042 | | cloudformation | admin | http://192.168.100.10:8000/v1 | | cloudformation | internal | http://192.168.100.10:8000/v1 | | cloudformation | public | http://192.168.100.10:8000/v1 | | compute | admin | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | compute | internal | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | compute | public | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | identity | admin | http://192.168.100.10:5000 | | identity | internal | http://192.168.100.10:5000 | | identity | public | http://192.168.100.10:5000 | | image | admin | http://192.168.100.10:9292 | | image | internal | http://192.168.100.10:9292 | | image | public | http://192.168.100.10:9292 | | metering | admin | http://192.168.100.10:8777 | | metering | internal | http://192.168.100.10:8777 | | metering | public | http://192.168.100.10:8777 | | metric | admin | http://192.168.100.10:8041 | | metric | internal | http://192.168.100.10:8041 | | metric | public | http://192.168.100.10:8041 | | network | admin | http://192.168.100.10:9696 | | network | internal | http://192.168.100.10:9696 | | network | public | http://192.168.100.10:9696 | | object-store | admin | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | object-store | internal | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | object-store | public | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | orchestration | admin | http://192.168.100.10:8004/v1/%(tenant_id)s | | orchestration | internal | http://192.168.100.10:8004/v1/%(tenant_id)s | | orchestration | public | http://192.168.100.10:8004/v1/%(tenant_id)s | | placement | admin | http://192.168.100.10:8778/placement | | placement | internal | http://192.168.100.10:8778/placement | | placement | public | http://192.168.100.10:8778/placement | | volumev2 | admin | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev2 | internal | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev2 | public | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev3 | admin | http://192.168.100.10:8776/v3/%(tenant_id)s | | volumev3 | internal | http://192.168.100.10:8776/v3/%(tenant_id)s | | volumev3 | public | http://192.168.100.10:8776/v3/%(tenant_id)s | +----------------+-----------+--------------------------------------------------+ 39 rows in set (0.001 sec) MariaDB [keystone]\u0026gt; SELECT s.type AS service_type, -\u0026gt; e.interface, -\u0026gt; e.url -\u0026gt; FROM endpoint e -\u0026gt; JOIN service s ON e.service_id = s.id -\u0026gt; WHERE e.interface = \u0026#39;public\u0026#39; -\u0026gt; ORDER BY s.type; +----------------+-----------+--------------------------------------------------+ | service_type | interface | url | +----------------+-----------+--------------------------------------------------+ | alarming | public | http://192.168.100.10:8042 | | cloudformation | public | http://192.168.100.10:8000/v1 | | compute | public | http://192.168.100.10:8774/v2.1/%(tenant_id)s | | identity | public | http://192.168.100.10:5000 | | image | public | http://192.168.100.10:9292 | | metering | public | http://192.168.100.10:8777 | | metric | public | http://192.168.100.10:8041 | | network | public | http://192.168.100.10:9696 | | object-store | public | http://192.168.100.10:8080/v1/AUTH_%(tenant_id)s | | orchestration | public | http://192.168.100.10:8004/v1/%(tenant_id)s | | placement | public | http://192.168.100.10:8778/placement | | volumev2 | public | http://192.168.100.10:8776/v2/%(tenant_id)s | | volumev3 | public | http://192.168.100.10:8776/v3/%(tenant_id)s | +----------------+-----------+--------------------------------------------------+ 13 rows in set (0.000 sec) MariaDB [keystone]\u0026gt; OpenStack デプロイ時のサービス作成\nデータベースに入り、データベース（例: glance）を作成します データベースユーザー glance を作成し、glance データベース内の全テーブルに対する ALL（参照・追加・更新・削除）権限を付与します glance サービスを作成し、glance-api のアドレス（エンドポイントアドレス）をデータベースに登録します ユーザーが glance-api にアクセスする必要がある場合、Keystone にリクエストを送り、Keystone データベースから glance api のエンドポイントアドレスを検索します\n1 2 #示例 如果将zlm用户加入admin角色，那他就拥有了admin角色权限 [root@Controller ~(keystone_admin)]# openstack role add --user zlm --project LMandMY_HOME admin ユーザーが nova-api にリクエストを送ると、nova-api は Keystone にユーザー身份とトークンの有効期限を検証させます。ユーザーにクラウドサーバー作成権限があるかは判定しません。権限の有無は各サービスのポリシーファイルに依存します\n1 2 3 4 5 6 7 8 9 [root@Controller nova]# cd /etc/openstack-dashboard/ [root@Controller openstack-dashboard]# ls cinder_policy.json keystone_policy.json neutron_policy.json nova_policy.json glance_policy.json local_settings nova_policy.d [root@Controller nova(keystone_user)]# cp /etc/openstack-dashboard/glance_policy.json /etc/glance/policy.json [root@Controller nova(keystone_user)]# openstack image create --container-format bare --disk-format qcow2 --file /root/cirros-0.3.5-x86_64-disk.img --public test2 [root@Controller nova(keystone_user)]# chgrp glance /etc/glance/policy.json [root@Controller nova(keystone_user)]# systemctl restart openstack-glance-api.service Nova サービス コントローラーノード\nnova-api モジュール\nnova-scheduler モジュール\nnova-conductor モジュール\nnova-novncproxy モジュール\nコンピュートノード\nnova-compute モジュール\nnova-api\n外部に公開する REST インターフェースの処理を担当\n渡されたパラメーターの妥当性検証と制約チェックを行います\nリクエストされたリソースのクォータ（quota）を検証し予約します\nリソースの作成・更新・削除・照会など\n仮想マシンのライフサイクルの入口\n水平方向にスケールアウトしてデプロイ可能\nnova-conductor\nnova-compute のデータベース直接アクセスを切り離します。ユーザーがクラウドサーバーの作成を申請し作成が成功すると、nova-conductor モジュールがクラウドサーバー情報をデータベースに書き込みます\ndatabase — そのコンポーネントに関連する情報（クラウドサーバー情報、イメージ情報、ネットワーク情報など）を保存します\nnova-scheduler\nOpenStack 環境に複数の Compute ノードがある場合、ユーザーがクラウドサーバーを作成すると nova-scheduler モジュールが各 compute ホストの重みに基づいて、そのサーバーをどのコンピュートノードで動かすかを決定します\nHAProxy がロードバランシングを提供します。ユーザーが nova-api にアクセスすると、リクエストはまず HAProxy に渡され、各 nova-api の負荷状況に応じてどの API ノードに送るかが決定されます\nMQ — Message Queue（メッセージキュー）\n1 つのコンポーネントが複数のモジュールを持つ場合、モジュール間のやり取りはメッセージキューを経由して輻輳制御などを行います\n1000 人のユーザーが nova-api にリクエストを送った場合\nnova-api はリクエストを nova-compute に送信します\nnova-api はこれら 1000 件のリクエストをメッセージキューに送り、メッセージキューは各 compute ホストのメッセージ消費状況と処理進捗に応じて、それらを順序立てて nova-compute ノードに配信して処理させます\nnova-compute\n実際に仮想マシンを動作させるモジュール\nnova-novncproxy\n動作原理：nova-compute ホストは稼働中の仮想マシンごとに VNC Server のポートを 1 つ開きます\nnova-compute ホストはそのポートを外部に公開してはいけません。公開するとインターネット上のホストがそのポートと仮想マシンにアクセスできてしまいます\nこの問題を解決するため、コントローラーノード上で nova-novncproxy サービスを起動して外部に提供します。ユーザーがその仮想マシンのコンソールにアクセスすると、まず nova-novncproxy にリクエストが送られ、提供された情報（仮想マシンの UUID、トークンなど）からその仮想マシンがどの nova-compute 上で動いているかを検索し、その Compute ホストへリクエストを転送します。\nVNC で仮想マシンを開く仕組み\nvncserver — 5900 番ポート\nvncviewer — vncviewer\nクライアントに vncviewer をインストールする必要はなく、その機能はブラウザの HTML に組み込まれています（noVNC プロトコル）\nGlance と Swift サービス 一、クラウドサーバーのデプロイ：\nユーザーがクラウドサーバーのデプロイ指令を送り検証を通過すると、nova-compute ホストは glance イメージサーバーからイメージをローカル（クラウドサーバーはローカルにデプロイ）にダウンロードします — /var/lib/nova/instances/_base/\nクラウドサーバーが起動すると差分ディスクが生成され、新しく書き込まれたデータはその差分ディスクに保存されます\n実験：glance イメージを glance のローカルディスクではなく Swift オブジェクトストレージに保存する\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@Controller ~]# cd /etc/glance/ [root@Controller glance]# cp glance-api.conf glance-api.conf.bak [root@Controller ~]# vim /etc/glance/glance-api.conf 3057 stores=file,http,swift 3111 default_store=swift 3982 swift_store_region = RegionOne 4032 swift_store_endpoint_type = publicURL 4090 swift_store_container = public 4118 swift_store_large_object_size = 5120 4142 swift_store_large_object_chunk_size = 100 4160 swift_store_create_container_on_put = True 4182 swift_store_multi_tenant = True 4230 swift_store_admin_tenants = services 4382 swift_store_auth_version = 2 4391 swift_store_auth_address = http://192.168.100.10:5000/v3 4399 swift_store_user = zlm 4408 swift_store_key = 000000 [root@Controller ~]# systemctl restart openstack-glance-api.service 備考：zlm ユーザーは swiftOperator ロールを付与されて初めて Swift への操作権限を持ちます\n","permalink":"https://LMDAWN1127.github.io/ja/posts/openstack-keystone-glance-nova/","summary":"OpenStack の 3 大中核サービスを整理：Keystone のマルチドメイン対応・service/endpoint 登録・ポリシーファイルによる権限制御、Nova の各モジュール（api/scheduler/conductor/compute/novncproxy）とメッセージキュー・差分ディスク、そして Glance イメージサービスの Swift オブジェクトストレージ化。","title":"OpenStack 中核サービス詳細解説：Keystone 認証・Nova コンピュート・Glance/Swift イメージストレージ"},{"content":"一、GUI（ダッシュボード）でのクラウドサーバー提供 admin ユーザーはクラウドのスーパー管理者です\nadmin はアイデンティティを管理します\n一、テナント（プロジェクト）の作成\n二、ユーザー作成とプロジェクト紐付け\n三、イメージのアップロード：管理者がアップロードしたイメージはパブリック（全テナントが利用可能）に設定でき、一般ユーザーがアップロードしたイメージはプライベートでテナント内でのみ共有されます。\n四、フレーバーの作成\n五、外部ネットワークの作成\nL3 Agent が配置されたノードがネットワークノードとなります\nテナントとしてログイン\n一、テナント身份でログイン\n二、プライベートネットワークとサブネット（VPC）の作成\n三、ルーター作成と外部ネットワーク・プライベートネットワークの接続\n四、セキュリティグループとルールの作成\n五、キーペアの作成\n六、クラウドサーバー提供と浮動 IP の紐付け\n七、テスト（ログイン・ホスト名・ネットワーク）\ncloud-init がホスト名やパスワードなどのカスタム情報を初期化します\n例えば 20GB のディスクを占有し、快適に動作させるために 4GB のメモリを必要とする大きなイメージを作成したとします。しかしテナントはそれを知らないため、サーバー提供時に 10GB ディスク・2GB メモリのフレーバーを選んで失敗し、原因も分かりません。そこでイメージ登録時に「最小ディスク 20GB・最小メモリ 4GB」を指定しておけば、後にフレーバーを選ぶ際にその条件を満たさないフレーバーは選択できず、条件を満たすものだけを選べるようになります。\n以下は OpenStack Nova において新たに追加されたコンピュートノードを所属する Cell データベースに発見・マッピングするために使う重要なコマンドです。Cells v2 アーキテクチャでは、各コンピュートノードはこの登録ステップを経る必要があり、さもないとスケジューラがその上にインスタンスを配置できず、API にもそのホストが表示されません。\n1 [root@Controller ~(keystone_admin)]# nova-manage cell_v2 discover_hosts --verbose クラウドサーバーはルーター経由でインターネットに出られます。浮动 IP を設定する意味は、外部にサービスを公開することです（Web サーバーは SNAT で外に出られますが、リモートユーザーはそのサービスに入ってこられません）。以下は OpenStack が裏で使っている iptables ルールを確認する方法です。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 [root@Controller ~(keystone_admin)]# ip netns qrouter-aa6470e8-9c0e-4a50-9be6-71566d0c3903 (id: 1) qdhcp-a82a6d9e-26ec-497f-8f71-68d8395386ad (id: 0) [root@Controller ~(keystone_admin)]# ip netns exec qrouter-aa6470e8-9c0e-4a50-9be6-71566d0c3903 ip addr list 1: lo: \u0026lt;LOOPBACK,UP,LOWER_UP\u0026gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 33: qg-d9305000-ef: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether fa:16:3e:18:37:69 brd ff:ff:ff:ff:ff:ff inet 192.168.10.106/24 brd 192.168.10.255 scope global qg-d9305000-ef valid_lft forever preferred_lft forever inet 192.168.10.182/32 brd 192.168.10.182 scope global qg-d9305000-ef valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe18:3769/64 scope link valid_lft forever preferred_lft forever 34: qr-eb02e78e-a3: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1450 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether fa:16:3e:18:b8:5f brd ff:ff:ff:ff:ff:ff inet 192.168.20.254/24 brd 192.168.20.255 scope global qr-eb02e78e-a3 valid_lft forever preferred_lft forever inet6 fe80::f816:3eff:fe18:b85f/64 scope link valid_lft forever preferred_lft forever [root@Controller ~(keystone_admin)]# ip netns exec qrouter-aa6470e8-9c0e-4a50-9be6-71566d0c3903 iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination neutron-l3-agent-PREROUTING all -- 0.0.0.0/0 0.0.0.0/0 Chain INPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination neutron-l3-agent-POSTROUTING all -- 0.0.0.0/0 0.0.0.0/0 neutron-postrouting-bottom all -- 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy ACCEPT) target prot opt source destination neutron-l3-agent-OUTPUT all -- 0.0.0.0/0 0.0.0.0/0 Chain neutron-l3-agent-OUTPUT (1 references) target prot opt source destination DNAT all -- 0.0.0.0/0 192.168.10.182 to:192.168.20.197 Chain neutron-l3-agent-POSTROUTING (1 references) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ! ctstate DNAT Chain neutron-l3-agent-PREROUTING (1 references) target prot opt source destination REDIRECT tcp -- 0.0.0.0/0 169.254.169.254 tcp dpt:80 redir ports 9697 DNAT all -- 0.0.0.0/0 192.168.10.182 to:192.168.20.197 Chain neutron-l3-agent-float-snat (1 references) target prot opt source destination SNAT all -- 192.168.20.197 0.0.0.0/0 to:192.168.10.182 random-fully Chain neutron-l3-agent-snat (1 references) target prot opt source destination neutron-l3-agent-float-snat all -- 0.0.0.0/0 0.0.0.0/0 SNAT all -- 0.0.0.0/0 0.0.0.0/0 to:192.168.10.106 random-fully SNAT all -- 0.0.0.0/0 0.0.0.0/0 mark match ! 0x2/0xffff ctstate DNAT to:192.168.10.106 random-fully Chain neutron-postrouting-bottom (1 references) target prot opt source destination neutron-l3-agent-snat all -- 0.0.0.0/0 0.0.0.0/0 /* Perform source NAT on outgoing traffic. */ 実験課題：インターネットにアクセスできるクラウドサーバーを作成し、yum リポジトリを Alibaba Cloud に向け、httpd パッケージをインストールしてサービスを起動し、外部ホストから Web ページ http://192.168.10.182 にアクセスする。\nCompute ホストは本質的に KVM ハイパーバイザーです。OpenStack がクラウドサーバーを提供する際、スケジューラがいずれかの Compute ホストに分散配置します。\n二、コマンドラインでのクラウドサーバー提供 1 [root@Controller ~(keystone_admin)]# cp keystonerc_admin keystonerc_zlm 要件一：コマンドラインで全リソースを削除\n1 2 3 4 5 6 7 8 9 10 11 12 [root@Controller ~(keystone_zlm)]# cat keystonerc_zlm unset OS_SERVICE_TOKEN export OS_USERNAME=zlm export OS_PASSWORD=\u0026#39;000000\u0026#39; export OS_REGION_NAME=RegionOne export OS_AUTH_URL=http://192.168.100.10:5000/v3 export PS1=\u0026#39;[\\u@\\h \\W(keystone_zlm)]\\$ \u0026#39; export OS_PROJECT_NAME=LMandMY_HOME export OS_USER_DOMAIN_NAME=Default export OS_PROJECT_DOMAIN_NAME=Default export OS_IDENTITY_API_VERSION=3 [root@Controller ~(keystone_zlm)]# source keystonerc_zlm クラウドサーバーの削除 1 2 3 4 5 6 7 [root@Controller ~(keystone_zlm)]# openstack server list +--------------------------------------+------+--------+--------------------------------------+------------------+--------+ | ID | Name | Status | Networks | Image | Flavor | +--------------------------------------+------+--------+--------------------------------------+------------------+--------+ | 44f0fa66-94ed-44ac-a9ae-0a3a13c1faba | web | ACTIVE | VPC01=192.168.20.197, 192.168.10.182 | CentOS 8.4 64bit | m3.web | +--------------------------------------+------+--------+--------------------------------------+------------------+--------+ [root@Controller ~(keystone_zlm)]# openstack server delete 44f0fa66-94ed-44ac-a9ae-0a3a13c1faba ボリュームの削除 1 2 [root@Controller ~(keystone_zlm)]# openstack volume list [root@Controller ~(keystone_zlm)]# openstack volume delete data01 ルーターの削除 1 2 3 4 5 [root@Controller ~(keystone_zlm)]# openstack router list [root@Controller ~(keystone_zlm)]# openstack router show router01 [root@Controller ~(keystone_zlm)]# openstack subnet list [root@Controller ~(keystone_zlm)]# openstack router remove subnet router01 subnet01 [root@Controller ~(keystone_zlm)]# openstack router delete router01 セキュリティグループの削除 1 2 [root@Controller ~(keystone_zlm)]# openstack security group list [root@Controller ~(keystone_zlm)]# openstack security group delete SG01 ネットワークの削除 1 2 [root@Controller ~(keystone_zlm)]# openstack network list [root@Controller ~(keystone_zlm)]# openstack network delete VPC01 admin 身份に切り替えて、パブリックネットワーク・イメージ・フレーバー・テナント・ユーザーなどを削除します。\n1 [root@Controller ~(keystone_zlm)]# source keystonerc_admin パブリックネットワークの削除 1 2 [root@Controller ~(keystone_admin)]# openstack network list [root@Controller ~(keystone_admin)]# openstack network delete public イメージの削除 1 2 3 4 [root@Controller ~(keystone_admin)]# openstack image list [root@Controller ~(keystone_admin)]# openstack image delete e3336d90-e673-4b1b-82ec-69b70fd6402c [root@Controller ~(keystone_admin)]# openstack image delete cec813dd-8141-4a99-8883-805ac6e3ec17 [root@Controller ~(keystone_admin)]# openstack image delete c6ffe7db-ccb0-4df4-8715-e8ce0fd5dc7d フレーバーの削除 1 2 [root@Controller ~(keystone_admin)]# openstack flavor list [root@Controller ~(keystone_admin)]# openstack flavor delete m3.web テナントとユーザーの削除 1 2 3 4 [root@Controller ~(keystone_admin)]# openstack project list [root@Controller ~(keystone_admin)]# openstack project delete LMandMY_HOME [root@Controller ~(keystone_admin)]# openstack user list [root@Controller ~(keystone_admin)]# openstack user delete zlm 要件二：コマンドラインで全リソースを作成—サーバー提供・浮动 IP 追加・サーバーアクセス・ネットワーク作成\n1 [root@Controller ~(keystone_admin)]# source keystonerc_admin プロジェクトとユーザーを作成し紐付け 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@Controller ~(keystone_admin)]# openstack project create LMandMY_HOME [root@Controller ~(keystone_admin)]# openstack user create --project LMandMY_HOME --project-domain Default --password-prompt zlm [root@Controller ~(keystone_admin)]# openstack role list +----------------------------------+------------------+ | ID | Name | +----------------------------------+------------------+ | 0adc17230a5a434195d5995863280b3d | heat_stack_owner | | 2e5abdde67bb4f23bbf15454616af53e | ResellerAdmin | | 46d49fecd6f4411bbd72d0b9f575bcae | admin | | 5f5bf78c40b143bbb2df74fc855ea204 | reader | | 84ebb81407f644b18e1a529e0c317f16 | member | | b83f4c27c83445489554e988fb9af5a1 | heat_stack_user | | b8f8cd45891240bfa0f80e93f0e37ab9 | _member_ | | ebc22a15458c4712bf0dd4f4de09e0bf | SwiftOperator | +----------------------------------+------------------+ [root@Controller ~(keystone_admin)]# openstack role add --user zlm --project LMandMY_HOME b8f8cd45891240bfa0f80e93f0e37ab9 イメージのアップロード 1 [root@Controller ~(keystone_admin)]# openstack image create --file /data/cirros-0.3.5-x86_64-disk.img --disk-format qcow2 --container-format bare --public cirros フレーバーの作成 1 [root@Controller ~(keystone_admin)]# openstack flavor create --ram 1024 --disk 10 --public m3.web パブリックネットワークとサブネットの作成 1 [root@Controller ~(keystone_admin)]# openstack network create --external --share --provider-network-type flat --provider-physical-network extnet --project LMandMY_HOME public サブネットの作成\n1 [root@Controller ~(keystone_admin)]# openstack subnet create --no-dhcp --subnet-range 192.168.10.0/24 --allocation-pool start=192.168.10.100,end=192.168.10.200 --gateway 192.168.10.1 --network public publicsub01 テナント身份に切り替え\n1 [root@Controller ~(keystone_admin)]# source keystonerc_zlm ネットワークとサブネットの作成 1 [root@Controller ~(keystone_zlm)]# openstack network create VPC01 サブネットの作成\n1 [root@Controller ~(keystone_zlm)]# openstack subnet create --network VPC01 --subnet-range 192.168.20.0/24 --dhcp --gateway 192.168.20.254 --dns-nameserver 114.114.114.114 subnet01 ルーターの作成 1 2 3 [root@Controller ~(keystone_zlm)]# openstack router create router01 [root@Controller ~(keystone_zlm)]# openstack router add subnet router01 subnet01 [root@Controller ~(keystone_zlm)]# openstack router set --external-gateway public router01 セキュリティグループの作成 1 [root@Controller ~(keystone_zlm)]# openstack security group create SG01 ICMP プロトコルを許可\n1 [root@Controller ~(keystone_zlm)]# openstack security group rule create --ingress --protocol icmp --remote-ip 0.0.0.0/0 SG01 SSH サービスを許可\n1 [root@Controller ~(keystone_zlm)]# openstack security group rule create --ingress --protocol tcp --dst-port 22 --remote-ip 0.0.0.0/0 SG01 ポート 80 を許可\n1 [root@Controller ~(keystone_zlm)]# openstack security group rule create --ingress --protocol tcp --dst-port 80 --remote-ip 0.0.0.0/0 SG01 フローティング IP の作成 1 [root@Controller ~(keystone_zlm)]# openstack floating ip create public キーペアの作成 1 [root@Controller ~(keystone_zlm)]# openstack key create key01 \u0026gt; key01.pem クラウドサーバーの作成 1 2 3 4 5 6 7 8 [root@Controller ~(keystone_zlm)]# openstack network list +--------------------------------------+--------+--------------------------------------+ | ID | Name | Subnets | +--------------------------------------+--------+--------------------------------------+ | a82a6d9e-26ec-497f-8f71-68d8395386ad | VPC01 | 40bd75e0-3d22-4e7b-8659-8a6c0a44e3aa | | d99ba601-05e3-4f1f-88b8-f0587c6a5f6e | public | 5d39db23-8359-4e33-bde7-0f9ac6a0f7c7 | +--------------------------------------+--------+--------------------------------------+ [root@Controller ~(keystone_zlm)]# openstack server create --image cirros --security-group SG01 --key-name key01 --flavor m3.web --nic net-id=a82a6d9e-26ec-497f-8f71-68d8395386ad web 浮动 IP をクラウドサーバーに紐付け\n1 2 [root@Controller ~(keystone_zlm)]# openstack port list [root@Controller ~(keystone_zlm)]# openstack floating ip set --port=46ba21d5-6f14-4693-a215-5a6fc8781adf 192.168.10.182 クラウドサーバーへのアクセス\n1 2 [root@Controller ~(keystone_zlm)]# chmod 400 key01.pem [root@Controller ~(keystone_zlm)]# ssh -i key01.pem cirros@192.168.10.182 外部ネットワークの NIC が通信できない場合\n1 [root@Controller ~(keystone_zlm)]# ifup br-ex ; ifup ens224 ","permalink":"https://LMDAWN1127.github.io/ja/posts/openstack-provision-cloud-server/","summary":"GUI から CLI まで、OpenStack でのクラウドサーバー提供の全体フローを完全解説：テナント・ユーザー・イメージ・フレーバー・ネットワーク・ルーター・セキュリティグループ・キーペア・浮动 IP の作成と削除、および iptables SNAT/DNAT と Nova cell_v2 discover_hosts のトラブルシューティング。","title":"OpenStack でのクラウドサーバー提供"},{"content":"01 - systemctl データベース Service ファイルの整理 方案1：標準本番デーモン設定 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [Unit] Description=MySQL Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid ExecReload=/bin/kill -HUP $MAINPID PIDFile=/var/run/mysqld/mysqld.pid PrivateTmp=true RuntimeDirectory=mysqld [Install] WantedBy=multi-user.target 方案2：設定ファイルとファイルハンドル制限付き 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [Unit] Description=MySQL Server After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf RuntimeDirectory=mysqld LimitNOFILE=65536 Restart=on-failure [Install] WantedBy=multi-user.target 修正完了後\n1 2 3 [root@master local]#systemctl daemon-reload [root@master local]#systemctl restart mysqld.service [root@master local]#systemctl enable mysqld.service 02 - マルチバージョン MySQL（5.6 / 5.7）インストールとアップグレード準備実戦 手順1：ソフトウェアアーカイブのダウンロード 1 2 3 4 5 # MySQL 5.7.40 バイナリパッケージ [root@master local]#wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.40-linux-glibc2.12-x86_64.tar.gz # MySQL 5.6.48 バイナリパッケージ [root@master local]#wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.48-linux-glibc2.12-x86_64.tar.gz 手順2：展開・インストールとシンボリックリンク作成 1 2 3 4 5 6 7 8 9 # 5.7 のインストール [root@master local]#tar xf mysql-5.7.40-linux-glibc2.12-x86_64.tar.gz [root@master local]#ln -s mysql-5.7.40-linux-glibc2.12-x86_64 mysql57 # 注意：マルチバージョン共存デバッグ中はグローバル環境変数を設定せず、コマンドパスの衝突を回避 # 5.6 のインストール [root@master local]#tar xf mysql-5.6.48-linux-glibc2.12-x86_64.tar.gz [root@master local]#ln -s mysql-5.6.48-linux-glibc2.12-x86_64 mysql56 # 注意：今のところグローバル環境変数は設定しない 手順3：データベースソフトウェアの初期化 MySQL 5.7 初期化（データディレクトリ 3357）:\n1 2 3 4 5 [root@master local]#mkdir -p /data/3357/data [root@master local]#chown -R mysql.mysql /data/3357/data [root@master local]#/usr/local/mysql57/bin/mysqld --initialize-insecure --user=mysql --datadir=/data/3357/data --basedir=/usr/local/mysql57 [root@master local]#echo $? 0 MySQL 5.6 初期化（データディレクトリ 3356）:\n1 2 3 4 5 6 7 8 9 10 11 [root@master local]#mkdir -p /data/3356/data [root@master local]#chown -R mysql.mysql /data/3356/data [root@master local]#/usr/local/mysql56/scripts/mysql_install_db --user=mysql --datadir=/data/3356/data --basedir=/usr/local/mysql56 FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql56/scripts/mysql_install_db: Data::Dumper # Perl モジュール不足 [root@master local]#yum install -y perl-Data-Dumper [root@master local]#/usr/local/mysql56/scripts/mysql_install_db --user=mysql --datadir=/data/3356/data --basedir=/usr/local/mysql56 # 出力に 2 つの OK が含まれるか確認し、終了コードを確認： [root@master local]#echo $? 0 手順4：マルチインスタンス専用設定ファイルの作成 MySQL 5.7（インスタンス 3357）設定:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@master local]#vim /etc/my3357.cnf [mysql] socket=/tmp/mysql3357.sock [mysqld] user=mysql basedir=/usr/local/mysql57 datadir=/data/3357/data socket=/tmp/mysql3357.sock port=3357 pid-file=/run/mysqld3357/mysqld.pid [root@master local]#vim /usr/lib/systemd/system/mysqld3357.service [Unit] Description=MySQL 5.7 Server (3357) After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql57/bin/mysqld --defaults-file=/etc/my3357.cnf RuntimeDirectory=mysqld3357 LimitNOFILE=65536 Restart=on-failure [Install] WantedBy=multi-user.target MySQL 5.6（インスタンス 3356）設定:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@master local]#vim /etc/my3356.cnf [mysql] socket=/tmp/mysql3356.sock [mysqld] user=mysql basedir=/usr/local/mysql56 datadir=/data/3356/data socket=/tmp/mysql3356.sock port=3356 pid-file=/run/mysqld3356/mysqld.pid [root@master local]#vim /usr/lib/systemd/system/mysqld3356.service [Unit] Description=MySQL 5.6 Server (3356) After=network.target [Service] User=mysql Group=mysql ExecStart=/usr/local/mysql56/bin/mysqld --defaults-file=/etc/my3356.cnf RuntimeDirectory=mysqld3356 LimitNOFILE=65536 Restart=on-failure [Install] WantedBy=multi-user.target 手順5：起動・管理の実行検証 MySQL 5.7 サービスの起動/停止:\n1 2 3 4 5 6 7 8 9 10 11 # 方式1：起動 [root@master local]#cp /usr/local/mysql57/support-files/mysql.server /etc/init.d/mysqld57 [root@master local]#chmod +x /etc/init.d/mysqld57 [root@master local]#/etc/init.d/mysqld57 start [root@master local]#/etc/init.d/mysqld57 stop # 方式2：起動 [root@master local]#systemctl daemon-reload [root@master local]#systemctl start mysqld3357.service [root@master local]#systemctl enable mysqld3357.service Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld3357.service to /usr/lib/systemd/system/mysqld3357.service. MySQL 5.6 サービスの起動/停止:\n1 2 3 4 5 6 7 8 9 10 11 # 方式1：起動 [root@master local]#cp /usr/local/mysql56/support-files/mysql.server /etc/init.d/mysqld56 [root@master local]#chmod +x /etc/init.d/mysqld56 [root@master local]#/etc/init.d/mysqld56 start [root@master local]#/etc/init.d/mysqld56 stop # 方式2：起動 [root@master local]#systemctl daemon-reload [root@master local]#systemctl start mysqld3356.service [root@master local]#systemctl enable mysqld3356.service Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld3356.service to /usr/lib/systemd/system/mysqld3356.service. 3 つのサービスの状態確認（すべて running）\n1 2 3 4 5 6 7 8 [root@master local]#for svc in mysqld mysqld3356 mysqld3357; do \u0026gt; a=$(systemctl show -p ActiveState \u0026#34;$svc\u0026#34; | cut -d= -f2) \u0026gt; s=$(systemctl show -p SubState \u0026#34;$svc\u0026#34; | cut -d= -f2) \u0026gt; echo \u0026#34;$svc: $a ($s)\u0026#34; \u0026gt; done mysqld: active (running) mysqld3356: active (running) mysqld3357: active (running) ","permalink":"https://LMDAWN1127.github.io/ja/posts/systemd-mysql-multiversion/","summary":"systemd Unit 管理と MySQL 5.6/5.7 のマルチバージョン・マルチインスタンス導入実戦：2 種類の本番デーモン設定、アーカイブ入手、初期化、インスタンス別設定ファイル作成、および起動/停止と 3 サービス状態確認。","title":"systemd サービス管理と MySQL マルチバージョン導入"},{"content":"01 - データベースサービスのインストールとデプロイ 1.1 データベースサーバーパッケージのダウンロード 公式ダウンロード先（過去のアーカイブバイナリパッケージ）：\n1 2 3 # 格納ディレクトリ [root@master ~]#cd /usr/local/ [root@master local]#wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz パッケージ情報を確認\n1 2 [root@master local]#ll mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz -rw-r--r-- 1 root root 914806904 Jul 2 2021 mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz 1.2 バイナリパッケージからのデータベースサーバーインストール 手順1：OS 環境の準備 1. ネットワークアドレスの確認 1 2 3 4 5 6 7 [root@master local]#ip addr show eth0 2: eth0: \u0026lt;BROADCAST,MULTICAST,UP,LOWER_UP\u0026gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:4b:b7:38 brd ff:ff:ff:ff:ff:ff inet 11.0.1.101/24 brd 11.0.1.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe4b:b738/64 scope link valid_lft forever preferred_lft forever 2. ホスト名解決の設定 1 2 3 4 [root@master local]#vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 11.0.1.101 master 3. システムファイアウォールを無効化 1 [root@master local]#systemctl disable firewalld --now 4. SELinux を無効化 1 2 3 4 5 [root@master local]#sed -i \u0026#39;s/^SELINUX=enforcing/SELINUX=disabled/\u0026#39; /etc/selinux/config # 再起動で反映 [root@master local]#reboot [root@master local]#getenforce Disabled 5. データベースインストール時の競合を回避 1 2 3 4 5 6 # システムに標準搭載の mariadb が存在するか確認 [root@master local]#rpm -qa | grep mariadb mariadb-libs-5.5.68-1.el7.x86_64 # システム標準のデータベースパッケージをアンインストール [root@master local]#yum remove -y mariadb-libs 6. データベース依存ソフトをインストール（欠けると初期化エラー） 1 [root@master local]#yum install -y libaio-devel 手順2：データベースソフトウェアのインストール 1. パッケージを展開しシンボリックリンクを作成（バージョン管理用） 1 2 [root@master local]#tar xf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz [root@master local]#ln -s mysql-8.0.26-linux-glibc2.12-x86_64 mysql 2. システム全体の環境変数を設定 1 2 3 4 5 [root@master local]#vim /etc/profile # ファイル末尾に追加 export PATH=$PATH:/usr/local/mysql/bin # 設定を反映 [root@master local]#source /etc/profile 3. インストールバージョンを確認 1 2 [root@master local]#mysql -V mysql Ver 8.0.26 for Linux on x86_64 (MySQL Community Server - GPL) 手順3：ソフトウェアの初期化 MySQL には2つのコアディレクトリがある：\nプログラムディレクトリ: /usr/local/mysql データディレクトリ: /data/3306/data（実際のデータを格納） 1. 専用実行ユーザーを作成（システムログイン不要） 1 [root@master local]#useradd mysql -M -s /sbin/nologin 2. データディレクトリを作成し権限を設定 1 2 [root@master local]#mkdir /data/3306/data -p [root@master local]#chown mysql.mysql /data/3306/data 3. データディレクトリを初期化 1 2 3 4 5 # 存在する可能性のある干渉設定ファイルを削除 [root@master local]#rm -f /etc/my.cnf # パスワードなし初期化を実行（初期化後管理者はパスワードなし） [root@master local]#mysqld --initialize-insecure --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql 手順4：データベースサービス設定ファイルの作成 /etc/my.cnf を作成・編集：\n1 2 3 4 5 6 7 8 9 10 [root@master local]#cat \u0026gt; /etc/my.cnf \u0026lt;\u0026lt; \u0026#39;eof\u0026#39; \u0026gt; [mysql] \u0026gt; socket=/tmp/mysql.sock \u0026gt; \u0026gt; [mysqld] \u0026gt; user=mysql \u0026gt; basedir=/usr/local/mysql \u0026gt; datadir=/data/3306/data \u0026gt; socket=/tmp/mysql.sock \u0026gt; eof 注: 設定ファイル内の basedir と datadir のパスは実際の環境に合わせて調整する。\n手順5：データベースサービスの起動 1. 公式サービス管理スクリプトで起動 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@master local]#cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld [root@master local]#/etc/init.d/mysqld start Starting MySQL.Logging to \u0026#39;/data/3306/data/master.err\u0026#39;. . SUCCESS! # 正常にデータベースに入れれば起動成功 [root@master local]#mysql -uroot Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 8 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; 2. コマンドラインから直接起動 mysqld コマンドで起動: 1 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql --socket=/tmp/mysql.sock \u0026amp; mysqld_safe セーフデーモンで起動: 1 /usr/local/mysql/bin/mysqld_safe --datadir=/data/3306/data \u0026amp; 3. systemctl / service で起動 方法1: 専用の Systemd Unit ファイルを作成 (/etc/systemd/system/mysqld.service) 方法2: /etc/init.d/ 配下のサービススクリプトを直接有効化・呼び出し： 1 2 3 4 systemctl enable mysqld service mysqld start # または systemctl start mysqld 1.3 補足知識 1. 初期化の2つの方法の比較 方法1：非セキュア初期化 (--initialize-insecure)\n1 mysqld --initialize-insecure --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql 特徴: データベース管理者にパスワードがなく、そのままパスワードなしでログインでき、テストやスクリプト初期化に便利。 方法2：セキュア初期化 (--initialize)\n1 mysqld --initialize --user=mysql --datadir=/data/3306/data --basedir=/usr/local/mysql 特徴: データベース管理者にランダムな一時パスワードが生成され、ログに出力され、初回ログインに使用する。 注意: 一時パスワードは初回ログイン専用。ログイン後は必ず新しいパスワードを再設定する必要があり、変更前は他の操作を実行できない： 1 ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; 2. 起動失敗の標準トラブルシューティング手順 手順1：システム基本環境の確認 SELinux が完全に無効化されているか確認； ポート 3306 が占有されていないか、他の競合するデータベースサービスプロセスが存在しないか確認。 手順2：エラーログの調査と分析 典型的なエラー: Starting MySQL. ERROR! ... PID file ... エラーログの詳細を確認： 1 2 3 cat /data/3306/data/master.err # ログエラー例: # 2024-06-14T09:15:36.120048Z 1 [ERROR] [MY-012271] [InnoDB] The innodb_system data file \u0026#39;ibdata1\u0026#39; must be writable 手順3：エラーログがない場合の調査方法 設定ファイル /etc/my.cnf を確認： 設定ファイルのパスとファイル名が正しいか確認； 設定ファイル内のパラメータ構文とパス設定が正しいか確認。 02 - データベースサービスの起動と停止 データベースサービスを起動・停止する方法は複数あり、一般的なものを以下にまとめる：\n番号 起動方法 対応する停止方法 説明と推奨 01 mysqld \u0026amp; kill / pkill / killall 非推奨；kill -9 の使用は厳禁 02 mysqld_safe \u0026amp; kill / pkill / killall 直接 kill は非推奨 03 mysql.server start mysql.server stop 公式ネイティブ制御スクリプト 04 service mysqld start service mysqld stop 推奨（古典的サービス管理） 05 systemctl start mysqld systemctl stop mysqld 推奨（現代 Linux 標準） 06 クライアント/管理コマンド mysqladmin -uroot -pパスワード shutdown 管理者がリモート/ローカル命令行から優雅に停止 07 SQL セッション内での停止 端末で shutdown; を実行 管理者権限が必要 03 - データベースサービスのパスワード管理 1. パスワードがない場合の設定 方法1：コマンドライン操作\n1 2 3 [root@master local]#mysqladmin -uroot password \u0026#39;123456\u0026#39; mysqladmin: [Warning] Using a password on the command line interface can be insecure. Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety. 方法2：SQL 文の操作\n1 2 mysql\u0026gt; ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;000000\u0026#39;; Query OK, 0 rows affected (0.02 sec) 2. 既存パスワードの変更 方法1：コマンドライン操作 1 2 3 [root@master local]#mysqladmin -uroot -p000000 password \u0026#39;123456\u0026#39; mysqladmin: [Warning] Using a password on the command line interface can be insecure. Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety. 方法2：SQL 文の操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@master local]#mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 14 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; Query OK, 0 rows affected (0.00 sec) mysql\u0026gt; 3. パスワードを忘れた場合（リセット） パスワードリセットの実践手順 手順1：データベースサービスを停止\n1 mysql\u0026gt; shutdown; またはシステム端末で実行：\n1 2 3 4 [root@master local]#service mysqld stop Shutting down MySQL.. SUCCESS! # または pkill mysqld 手順2：セーフモードで起動（権限テーブル読み込みをスキップし、パスワードなしログインを実現）\n1 2 [root@master local]#/usr/local/mysql/bin/mysqld_safe --datadir=/data/3306/data --skip-grant-tables --skip-networking \u0026amp; [1] 2658 説明: --skip-networking はネットワークリスニングを無効にし、パスワードなし期間中に他のネットワーククライアントが介入するのを防ぐ。\n手順3：パスワードなしでログインし、リセット\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@master local]#mysql Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 7 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec) mysql\u0026gt; ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; Query OK, 0 rows affected (0.00 sec) mysql\u0026gt; MySQL ターミナルで順に実行：\n1 2 3 4 5 6 7 -- 1. 権限テーブルをフラッシュ（メモリとディスクの権限テーブルを同期） -- 作用1：メモリ上の権限テーブル情報をディスクに同期書き込み -- 作用2：ディスク上の権限テーブル情報をメモリに再読み込み FLUSH PRIVILEGES; -- 2. パスワードをリセット ALTER USER root@\u0026#39;localhost\u0026#39; IDENTIFIED BY \u0026#39;123456\u0026#39;; 注意: FLUSH PRIVILEGES; を実行せずに ALTER USER を直接実行すると、システムがエラーをスローする：\n1 ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement 手順4：データベースサービスを正常に再起動\n1 2 3 4 5 6 7 # 一時セーフモードプロセスを終了 [root@master local]#pkill mysqld # データベースサービスを正常に起動 [root@master local]#/etc/init.d/mysqld start Starting MySQL.. SUCCESS! # または service mysqld start 手順5：新しいパスワードでログイン検証\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [root@master local]#mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \\g. Your MySQL connection id is 8 Server version: 8.0.26 MySQL Community Server - GPL Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. mysql\u0026gt; ","permalink":"https://LMDAWN1127.github.io/ja/posts/mysql-binary-deploy/","summary":"MySQL 8.0 の運用実戦：公式バイナリパッケージからのインストール、OS 準備、初期化、設定ファイル、複数の起動/停止方法、およびパスワード設定・変更・リセット。","title":"MySQL 実践：バイナリインストール・起動停止・パスワード管理"},{"content":"01. SonarQube 概要 1 2 3 1. SonarQube は Java で開発されており、Open JDK 8 が必要 2. SonarQube は MySQL データベースに依存し、少なくとも 5.6 以上 3. SonarQube の小規模インスタンスは最低 4G、大規模インスタンスは 16G のメモリが必要 02. デプロイ 1. JDK 実行環境をインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@sonarqube ~]#ll total 166040 -rw-r--r-- 1 root root 170023183 Oct 1 22:32 jdk-8u181-linux-x64.rpm [root@sonarqube ~]#rpm -ivh jdk-8u181-linux-x64.rpm warning: jdk-8u181-linux-x64.rpm: Header V3 RSA/SHA256 Signature, key ID ec551f03: NOKEY Preparing... ################################# [100%] Updating / installing... 1:jdk1.8-2000:1.8.0_181-fcs ################################# [100%] Unpacking JAR files... tools.jar... plugin.jar... javaws.jar... deploy.jar... rt.jar... jsse.jar... charsets.jar... localedata.jar... 2. データベースをインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # 1. MySQL 公式 Yum リポジトリ設定ファイルをダウンロード [root@sonarqube ~]#wget dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm # 2. MySQL リポジトリをインストール [root@sonarqube ~]#rpm -ivh mysql-community-release-el6-5.noarch.rpm Preparing... ################################# [100%] Updating / installing... 1:mysql-community-release-el6-5 ################################# [100%] # 3. MySQL サーバーをインストール [root@sonarqube ~]# yum install mysql-community-server -y [root@sonarqube ~]#mysql --version mysql Ver 14.14 Distrib 5.6.51, for Linux (x86_64) using EditLine wrapper # 4. MySQL サービスを起動 [root@sonarqube ~]#service mysqld start Starting mysqld (via systemctl): [ OK ] [root@sonarqube ~]#netstat -ntpl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1227/master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1008/sshd tcp6 0 0 ::1:25 :::* LISTEN 1227/master tcp6 0 0 :::3306 :::* LISTEN 3113/mysqld tcp6 0 0 :::22 :::* LISTEN 1008/sshd # 5. パスワードを設定 [root@sonarqube ~]# mysqladmin -uroot password 000000 # 6. sonarqube データベースを作成 [root@sonarqube ~]# mysql -uroot -p000000 -e \u0026#34;CREATE DATABASE sonarqube DEFAULT CHARACTER SET utf8;\u0026#34; [root@sonarqube ~]#mysql -u root -p000000 -e \u0026#34;show databases\u0026#34; Warning: Using a password on the command line interface can be insecure. +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sonarqube | +--------------------+ 3. SonarQube をインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 # 1. SonarQube パッケージをアップロード [root@sonarqube ~]# cd /usr/local/ [root@sonarqube local]#ll sonarqube-7.0.zip -rw-r--r-- 1 root root 155709573 Oct 1 22:50 sonarqube-7.0.zip # 2. 現在のディレクトリに展開 [root@sonarqube local]#yum install -y unzip [root@sonarqube local]# unzip sonarqube-7.0.zip [root@sonarqube local]# ln -s sonarqube-7.0 sonarqube # 3. プラグインをインストール: 既定のプラグインを削除: [root@sonarqube ~]# rm -rf /usr/local/sonarqube/extensions/plugins/* プラグインをアップロード: [root@sonarqube ~]#ll sonar_plugins.tar.gz -rw-r--r-- 1 root root 45106788 Oct 1 22:56 sonar_plugins.tar.gz [root@sonarqube ~]#tar xf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions/plugins/ [root@sonarqube ~]#ll /usr/local/sonarqube/extensions/plugins/ total 4 drwxr-xr-x 2 1000 1000 4096 Oct 24 2019 plugins [root@sonarqube ~]# cd /usr/local/sonarqube/extensions/plugins/ [root@sonarqube plugins]# mv plugins/* . [root@sonarqube plugins]#rm -fr plugins/ # 4. 一般ユーザーを作成 [root@sonarqube ~]# useradd sonarqube # 5. コードの所有者を sonarqube に変更 [root@sonarqube ~]# chown -R sonarqube.sonarqube /usr/local/sonarqube/ [root@sonarqube ~]# ll /usr/local/sonarqube/ total 12 drwxr-xr-x 8 sonarqube sonarqube 136 Feb 2 2018 bin drwxr-xr-x 2 sonarqube sonarqube 50 May 15 15:09 conf -rw-r--r-- 1 sonarqube sonarqube 7651 Feb 2 2018 COPYING drwxr-xr-x 2 sonarqube sonarqube 24 Feb 2 2018 data drwxr-xr-x 7 sonarqube sonarqube 150 Feb 2 2018 elasticsearch drwxr-xr-x 4 sonarqube sonarqube 40 Feb 2 2018 extensions drwxr-xr-x 9 sonarqube sonarqube 138 Feb 2 2018 lib drwxr-xr-x 2 sonarqube sonarqube 6 Feb 2 2018 logs drwxr-xr-x 2 sonarqube sonarqube 24 Feb 2 2018 temp drwxr-xr-x 9 sonarqube sonarqube 4096 Feb 2 2018 web # 6. データベース接続を設定 [root@sonarqube ~]#vim /usr/local/sonarqube/conf/sonar.properties ... sonar.jdbc.username=root # データベースユーザー名 sonar.jdbc.password=000000 # データベースパスワード #----- Embedded Database (default) # H2 embedded database server listening port, defaults to 9092 #sonarqube.embeddedDatabase.port=9092 #----- MySQL 5.6 or greater # Only InnoDB storage engine is supported (not myISAM). # Only the bundled driver is supported. It can not be changed. sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarqube?useUnicode=true\u0026amp;characterE ncoding=utf8\u0026amp;rewriteBatchedStatements=true\u0026amp;useConfigs=maxPerformance\u0026amp;useSSL =false # ローカル接続を有効化 ... 4. SonarQube を起動 1 2 SonarQube は root では起動できず、一般ユーザーで実行する必要がある [root@sonarqube ~]# su - sonarqube -c \u0026#34;/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start\u0026#34; 5. リモートアクセストークンを設定 起動後はポート 9000 で、ブラウザで http://11.0.1.202:9000/about を開き、admin / admin でログインし、トークンを生成する（一度しか表示されないので控えておく）。\n1 2 3 4 5 [root@jenkins ~]# sonar-scanner \\ -Dsonar.projectKey=html \\ -Dsonar.sources=. \\ -Dsonar.host.url=http://11.0.1.202:9000 \\ -Dsonar.login=a3bd8e829343edabbbc58fefe0d3e97fdb12268b 6. クライアントのデプロイ クライアントIP: 11.0.1.201\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # 1. クライアントをアップロード [root@jenkins ~]# cd /usr/local/ [root@jenkins ~]#ll sonar-scanner-cli-4.2.0.1873-linux.zip -rw-r--r-- 1 root root 42397119 Oct 2 00:09 sonar-scanner-cli-4.2.0.1873-linux.zip # 2. 展開してシンボリックリンクを作成 [root@jenkins local]#yum install -y unzip [root@jenkins local]#unzip /root/sonar-scanner-cli-4.2.0.1873-linux.zip [root@jenkins local]# ln -s sonar-scanner-4.2.0.1873-linux sonar # 3. グローバル PATH 変数を設定 [root@jenkins ~]# export PATH=\u0026#34;$PATH:/usr/local/sonar/bin/\u0026#34; # 4. 変数を /etc/profile に永続化 [root@jenkins ~]# vim /etc/profile .. export PATH=\u0026#34;$PATH:/usr/local/sonar/bin/\u0026#34; # 5. クライアントからサーバーにコードをスキャンして解析テスト /var/lib/jenkins/workspace/test_job/ 配下の blog コードを SonarQube にプッシュしてテスト [root@jenkins ~]#cd /var/lib/jenkins/workspace/test_job/ [root@jenkins test_job]#ll total 8 -rw-r--r-- 1 root root 7 Oct 1 20:32 a.txt -rw-r--r-- 1 root root 3634 Oct 1 20:32 blog_state.txt -rw-r--r-- 1 root root 0 Oct 1 21:12 c.txt drwxr-xr-x 2 root root 6 Oct 1 20:32 myblog drwxr-xr-x 2 root root 6 Oct 1 20:32 myblog-deploy [root@jenkins test_job]#sonar-scanner \\ -Dsonar.projectKey=html \\ -Dsonar.sources=. \\ -Dsonar.host.url=http://11.0.1.202:9000 \\ -Dsonar.login=a3bd8e829343edabbbc58fefe0d3e97fdb12268b 実行成功:\nサーバーを確認: アップロード成功\n","permalink":"https://LMDAWN1127.github.io/ja/posts/sonarqube-practice/","summary":"SonarQube を自前で導入する実践手順：JDK8/MySQL5.6 の導入、プラグイン込みの展開、非 root ユーザーでの起動、Web トークン設定、sonar-scanner クライアントによるコードスキャン。","title":"SonarQube 実践：プライベート導入・トークン設定・コード品質スキャン"},{"content":"01. Jenkins 概要 公式サイト：jenkins.io\nJenkins はオープンソースのプロジェクトで、Java ベースの継続的インテグレーション（CI）ツールである。繰り返しの作業を監視し、オープンで使いやすいソフトウェアプラットフォームを提供し、ソフトウェアの CI を可能にする。\n02. Jenkins のデプロイ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 I. 環境準備 1、OS：CentOS 7.9 2、メモリ：実験用 2G、本番用 6G 以上 3、ファイアウォールを無効化し、SELinux を無効にする 4、JDK17 II. JDK をインストール RPM パッケージをアップロード [root@jenkins ~]#ll total 178212 -rw-r--r-- 1 root root 182486159 Oct 1 19:04 jdk-17_linux-x64_bin.rpm [root@jenkins ~]#rpm -ivh jdk-17_linux-x64_bin.rpm warning: jdk-17_linux-x64_bin.rpm: Header V3 RSA/SHA256 Signature, key ID ad986da3: NOKEY Preparing... ################################# [100%] Updating / installing... 1:jdk-17-2000:17.0.11-7 ################################# [100%] インストールが成功したか確認： [root@jenkins ~]# rpm -qa|grep jdk jdk-17-17.0.11-7.x86_64 II. Jenkins をインストール Jenkins パッケージをアップロード [root@jenkins ~]#ll total 269432 -rw-r--r-- 1 root root 182486159 Oct 1 19:04 jdk-17_linux-x64_bin.rpm -rw-r--r-- 1 root root 93405530 Oct 1 19:06 jenkins-2.405-1.1.noarch.rpm [root@jenkins ~]#rpm -ivh jenkins-2.405-1.1.noarch.rpm warning: jenkins-2.405-1.1.noarch.rpm: Header V4 RSA/SHA512 Signature, key ID ef5975ca: NOKEY Preparing... ################################# [100%] Updating / installing... 1:jenkins-2.405-1.1 ################################# [100%] III. Jenkins の実行ユーザーを root に変更 1) 設定ファイルの実行ユーザーを変更 [root@jenkins ~]# vim /etc/sysconfig/jenkins ... JENKINS_USER=\u0026#34;root\u0026#34; ... 2) 起動設定のユーザーを変更 [root@jenkins ~]# vim /usr/lib/systemd/system/jenkins.service ... User=root Group=root ... [root@jenkins ~]# systemctl daemon-reload 3) フォント設定をインストール [root@jenkins ~]# yum -y install fontconfig IV. Jenkins を起動し、起動時に有効化 [root@jenkins ~]# systemctl start jenkins [root@jenkins ~]# systemctl enable jenkins 03. Jenkins へログイン 04. パスワードを変更 パスワード変更後は再ログイン（ユーザー名は admin）\n05. プラグインのインストール 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1. プラグインを Jenkins のホームディレクトリにアップロード [root@jenkins ~]# cd /var/lib/jenkins/ [root@jenkins ~]#ll total 576228 -rw-r--r-- 1 root root 182486159 Oct 1 19:04 jdk-17_linux-x64_bin.rpm -rw-r--r-- 1 root root 93405530 Oct 1 19:06 jenkins-2.405-1.1.noarch.rpm -rw-r--r-- 1 root root 314156543 Oct 1 19:30 jenkins_plu.tar.gz 2. プラグインを plugins ディレクトリに展開 [root@jenkins jenkins]#tar xf /root/jenkins_plu.tar.gz -C plugins/ 3. Jenkins を再起動して反映 [root@jenkins ~]# systemctl restart jenkins 06. プロジェクトを作成 フリープロジェクトを作成し、pwd を実行して Jenkins が使用する既定の作業ディレクトリを確認\n補足：Jenkins がプロジェクトを作成すると、ホーム /var/lib/jenkins/ 配下に workspace ディレクトリを自動作成し、その中にプロジェクト名のディレクトリを作成する。\n以降、Jenkins が GitLab からプルしたコードはこのプロジェクトディレクトリ配下に格納される。\n1 2 [root@jenkins ~]#ls /var/lib/jenkins/workspace/ test_job GitLab と Jenkins を連携させる\n連携前は接続できない旨が表示される：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # 鍵認証（非対話）を設定 [root@jenkins ~]#ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory \u0026#39;/root/.ssh\u0026#39;. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:Rr4ouinx/cPqVxJsxju2Cjd1mhWmWSuKGOKG532uTvk root@jenkins The key\u0026#39;s randomart image is: +---[RSA 2048]----+ | | | | | o = | | *B o | |o o=oS | |=o . +=O.. | |o=+.Bo+=. | |oo.B.+* | | .=+BOE. | +----[SHA256]-----+ [root@jenkins ~]#cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+kaj/NEwHKaIErMEClVYuG3JuWr9CD7XpuO5YZ6JftMmNdAPMrvS0mWqP4SDyT6/le0j1RGkA48GsirESfMqXKvzSSd5AuhIPmUADtGPNK6VSeiMKyoWgiNBFLn6RIOAcXI0MuZrYQMLJz+kOYr6kF9em/6MfFQrLkt9DzIlnR9b7CMLyDnPOZ8FG640DqqX0sZ8G+i2v41VX/c7RGIWAgEhJY+kiMS5cDxWlTf2k8hoZmh0VIa/G9AwnvbklyUiE4ACd9GtEJG5xXJzedn7q0/Ygfr26T29t+KST3SlyrXIaEbEC5WwIMymCEJDCPPCGzqLjsWa+4dbJhoEM1afV root@jenkins # Jenkins に git をインストール [root@jenkins ~]#yum install -y git GitLab に Jenkins が生成した鍵を追加：\nJenkins 上で一度 git clone し、初回の yes 入力を完了させる\n1 2 3 4 5 6 7 8 9 10 11 12 13 [root@jenkins ~]#git clone git@11.0.1.200:dawn/blog.git Cloning into \u0026#39;blog\u0026#39;... The authenticity of host \u0026#39;11.0.1.200 (11.0.1.200)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:Ldn1vBzBEFxynXs0qBNr0XzJ2lTx/0caMuK5yJtb+Zo. ECDSA key fingerprint is MD5:3d:1d:28:3f:33:ec:ee:c1:69:83:af:14:a3:7f:79:ac. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;11.0.1.200\u0026#39; (ECDSA) to the list of known hosts. remote: Enumerating objects: 20, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (8/8), done. remote: Total 20 (delta 0), reused 0 (delta 0), pack-reused 11 Receiving objects: 100% (20/20), done. Resolving deltas: 100% (2/2), done. これで接続できるようになる\n再度ビルドしてプルをテスト\nプル成功\nWebhook を設定\nWebhook を設定し、GitLab のコードを Jenkins が自動的にプルしてビルドするよう構成\n両方保存してテスト\nプロジェクトを修正して再度プッシュしてテスト\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [root@gitlab blog]#git branch * master [root@gitlab blog]#touch c.txt [root@gitlab blog]#git add . [root@gitlab blog]#git commit -m \u0026#34;test_v2\u0026#34; [master 7b1f29e] test_v2 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 c.txt [root@gitlab blog]#git pull origin master remote: Enumerating objects: 17, done. remote: Counting objects: 100% (9/9), done. remote: Compressing objects: 100% (8/8), done. remote: Total 17 (delta 0), reused 0 (delta 0), pack-reused 8 Unpacking objects: 100% (17/17), done. From 11.0.1.200:dawn/blog * branch master -\u0026gt; FETCH_HEAD Merge made by the \u0026#39;recursive\u0026#39; strategy. a.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 a.txt [root@gitlab blog]#git push -u origin master Counting objects: 7, done. Delta compression using up to 2 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 469 bytes | 0 bytes/s, done. Total 5 (delta 2), reused 0 (delta 0) To git@11.0.1.200:dawn/blog.git 47f606c..91e80a5 master -\u0026gt; master Branch master set up to track remote branch master from origin. 自動ビルド成功\n","permalink":"https://LMDAWN1127.github.io/ja/posts/jenkins-practice/","summary":"Jenkins を自前で導入する実践手順：JDK/Jenkins の RPM インストール、root 起動、プラグインのオフライン導入、GitLab の SSH 鍵認証と webhook 自動ビルドの連携。","title":"Jenkins 実践：プライベート導入・プラグイン導入・GitLab 連携 CI"},{"content":"01. GitLab 関連サイト 公式サイト：https://about.gitlab.com/\n国内ミラー：https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/\n02. GitLab のデプロイ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 I. 環境準備 1、OS：CentOS 7.9 2、メモリ：実験用 4G、本番用 8G 以上 3、ファイアウォールを無効化し、SELinux を無効にする II. GitLab の RPM パッケージをダウンロード [root@gitlab ~]# wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm III. GitLab をインストール # インストール中に依存関係のインストールが必要 [root@gitlab ~]# rpm -ivh gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm warning: gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID f27eab47: NOKEY error: Failed dependencies: policycoreutils-python is needed by gitlab-ce-16.9.8-ce.0.el7.x86_64 # 依存関係をインストール [root@gitlab ~]# yum -y install policycoreutils-python # 依存関係インストール後に GitLab のインストールを続行 [root@gitlab ~]# rpm -ivh gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm warning: gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID f27eab47: NOKEY Preparing... ################################# [100%] Updating / installing... 1:gitlab-ce-16.9.8-ce.0.el7 ################################# [100%] IV. 起動前にアクセス用ドメインまたは IP を設定 [root@gitlab ~]# vim /etc/gitlab/gitlab.rb ... external_url \u0026#39;http://11.0.1.200\u0026#39; ... 設定後、以下のコマンドを実行： [root@gitlab ~]# gitlab-ctl reconfigure 03. GitLab のコンポーネント 1 2 3 4 5 6 7 nginx： 静的 Web サーバー gitlab-workhorse: 軽量なリバースプロキシ logrotate： ログ管理ツール postgresql： データベース redis： キャッシュデータベース sidekiq： バックグラウンドのキュージョブを実行（非同期）。（Ruby） unicorn：Rack アプリケーション用 HTTP サーバー。GitLab の Rails アプリはこのサーバーでホストされる。（Ruby Web サーバー、主に Ruby で記述） 04. よく使う GitLab コマンド 1 2 3 4 5 gitlab-ctl start # GitLab を起動（gitlab-ctl reconfigure 後は自動起動） gitlab-ctl status # GitLab 全サービスの稼働状態を確認 gitlab-ctl stop # GitLab サービスを停止 gitlab-ctl stop nginx # 個別のサービスを停止 gitlab-ctl tail # 全サービスのログを表示 05. GitLab Web UI の設定 GitLab へログイン：11.0.1.200\n1. ログインパスワード gitlab-ctl reconfigure 完了後、パスワードの保存場所が表示される：\n2. UI 言語を中国語にする 3. デフォルトパスワードを変更 4. Webhook のローカルネットワーク要求を許可 06. GitLab 実践 1. グループを作成 2. グループ配下にプロジェクトを作成 これで最初のコードリポジトリが作成されたが、中身は空。次にコードをアップロードする\n3. コードをプロジェクトにコミット プロジェクト作成後、blog のコードをこのプロジェクトにアップロードする\nサーバーとコードリポジトリの接続方法は 2 つある\n1 つ目：ユーザー名とパスワードで接続\n2 つ目：SSH 鍵認証（非対話）で接続\n私たちは鍵認証方式を使う：便利でセキュリティも高い\n鍵ペアを生成（ここでは GitLab サーバーを直接使用） 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 [root@gitlab ~]#ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory \u0026#39;/root/.ssh\u0026#39;. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:j3FozajJdufxM0ZRtgPa2ZNSwWKvo8bvxbMJl8F5V3M root@gitlab The key\u0026#39;s randomart image is: +---[RSA 2048]----+ | ... | | + = | | + X +E| | =. =.B.+| | S + ++oo| | . + = +. +.| | = o.+o..* | | . . o+o++ + | | ..++oo | +----[SHA256]-----+ 鍵ペアを確認： [root@gitlab ~]# ll .ssh/ total 8 -rw------- 1 root root 1679 May 14 15:02 id_rsa # 秘密鍵 -rw-r--r-- 1 root root 393 May 14 15:02 id_rsa.pub # 公開鍵 [root@gitlab ~]#cat .ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJGpCKL64eidZ3I/nAVNCNJwD8yeDqelZP0GUTwlcp6IdKaZ7wUOIRDCtGn5r+YnOCKNwMhUNzb3VCOSVLDVIE0x53dPrCMK4OKLmZ6OtTYFBveGOZWWwdYyGQITx2eP7zOSBxeW3AnEWcya/UZdiZrYXA/d29DWjMjCt5QAxOit0EWSir1Z4i2MkTPuljOmjk6A55XAoem0WJRdg/d8KKIiCdcGrj4adYq2kNJ8oYH/9QcnpASUW/ANhzrALnLIX2WaH/p0T3gisLvk2KDUe3rVKD3XaKDlyLgWIViQFm3Me6L2e4taRFiu3VdsbfFfzjDevfDtLaqKLOqPtaczlF root@gitlab 生成した公開鍵を GitLab の SSH 鍵管理ページに貼り付ける これでサーバーと GitLab UI 間の SSH 鍵認証が完了。次にコードを blog プロジェクトにプッシュする\nコードをプッシュする方法は 2 つある：\n空のリポジトリをローカルにクローンし、コードをコピーしてからリモート GitLab にコミットする プロジェクト内でリンクアドレスを確認する\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 1. リンクをコピーして実行 [root@gitlab ~]#git clone git@11.0.1.200:dawn/blog.git Cloning into \u0026#39;blog\u0026#39;... The authenticity of host \u0026#39;11.0.1.200 (11.0.1.200)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:Ldn1vBzBEFxynXs0qBNr0XzJ2lTx/0caMuK5yJtb+Zo. ECDSA key fingerprint is MD5:3d:1d:28:3f:33:ec:ee:c1:69:83:af:14:a3:7f:79:ac. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;11.0.1.200\u0026#39; (ECDSA) to the list of known hosts. warning: remote HEAD refers to nonexistent ref, unable to checkout. 2. blog リポジトリがローカルにダウンロードされたことを確認 [root@gitlab ~]#ll total 1176964 drwxr-xr-x 3 root root 18 Oct 1 14:43 blog -rw-r--r-- 1 root root 84579612 Oct 1 14:35 blog_backup_20261001-1435.tar.gz drwxr-xr-x 3 root root 18 Sep 30 19:14 dawn -rw-r--r-- 1 root root 1120627456 Sep 30 23:12 gitlab-ce-16.9.8-ce.0.el7.x86_64.rpm 3. blog ディレクトリに入る [root@gitlab ~]#cd blog/ 4. コードを展開： [root@gitlab blog]#tar xf /root/blog_backup_20261001-1435.tar.gz -C . 5. コードをローカルリポジトリにコミット [root@gitlab blog]#git add . [root@gitlab blog]#git commit -m \u0026#34;DAWN’s Blog\u0026#34; [master (root-commit) 5af4246] DAWN’s Blog 3 files changed, 112 insertions(+) create mode 100644 blog_state.txt create mode 160000 myblog create mode 160000 myblog-deploy 6. コードをリモート GitLab の blog リポジトリにプッシュ GitLab リポジトリを直接クローンしたため、ローカルディレクトリにはすでにリモート blog プロジェクトのアドレスが設定されている リモートリポジトリを確認： [root@gitlab blog]#git remote -v origin git@11.0.1.200:dawn/blog.git (fetch) origin git@11.0.1.200:dawn/blog.git (push) ローカルの master をリモート origin にプッシュ [root@gitlab blog]#git push -u origin master Counting objects: 3, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 1.23 KiB | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@11.0.1.200:dawn/blog.git * [new branch] master -\u0026gt; master Branch master set up to track remote branch master from origin. blog プロジェクトを確認、コードのアップロード成功\nローカル Git リポジトリをリモート GitLab にプッシュ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 1. ローカルリポジトリを設定 [root@gitlab ~]#mkdir dawn [root@gitlab ~]#cd dawn 2. リポジトリを初期化 [root@gitlab dawn]#git init 3. コードをアップロード [root@gitlab dawn]#touch a.txt [root@gitlab dawn]#git add . [root@gitlab dawn]#git commit -m \u0026#34;test_v1\u0026#34; [master (root-commit) 815c600] test_v1 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a.txt 4. GitLab の blog リポジトリをローカルのリモートに設定 [root@gitlab dawn]#git remote add origin git@11.0.1.200:dawn/blog.git 5. ローカル内容をリモートにプッシュ（リモートにすでに内容があるため直接プッシュはエラーになる。リモート内容を保持するため、先に pull してマージしてからプッシュする） [root@gitlab dawn]#git pull origin master warning: no common commits remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From 11.0.1.200:dawn/blog * branch master -\u0026gt; FETCH_HEAD Merge made by the \u0026#39;recursive\u0026#39; strategy. blog_state.txt | 110 ++++++++++++++++++++++++++++++++++++ myblog | 1 + myblog-deploy | 1 + 3 files changed, 112 insertions(+) create mode 100644 blog_state.txt create mode 160000 myblog create mode 160000 myblog-deploy [root@gitlab dawn]#git push -u origin master Counting objects: 6, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 462 bytes | 0 bytes/s, done. Total 5 (delta 1), reused 0 (delta 0) To git@11.0.1.200:dawn/blog.git 5af4246..0242e0a master -\u0026gt; master Branch master set up to track remote branch master from origin. 一般ユーザー dev を作成 作成後、dev のパスワードを変更（ログアウトしないこと。ユーザー画面の編集をクリック）\nその後、dev で GitLab にログイン（初回ログイン時にパスワード変更が必要）\ndev ユーザーを dawn グループに追加 dev サーバーで鍵ペアを生成 1 [root@lb01 ~]#ssh-keygen 生成した公開鍵を dev アカウントの SSH 鍵ページにコピー コードを dev ホスト 11.0.1.5 にクローン 1 2 3 4 5 6 7 8 9 10 11 12 13 [root@lb01 ~]#git clone git@11.0.1.200:dawn/blog.git Cloning into \u0026#39;blog\u0026#39;... The authenticity of host \u0026#39;11.0.1.200 (11.0.1.200)\u0026#39; can\u0026#39;t be established. ECDSA key fingerprint is SHA256:Ldn1vBzBEFxynXs0qBNr0XzJ2lTx/0caMuK5yJtb+Zo. ECDSA key fingerprint is MD5:3d:1d:28:3f:33:ec:ee:c1:69:83:af:14:a3:7f:79:ac. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;11.0.1.200\u0026#39; (ECDSA) to the list of known hosts. remote: Enumerating objects: 8, done. remote: Counting objects: 100% (8/8), done. remote: Compressing objects: 100% (6/6), done. remote: Total 8 (delta 1), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (8/8), done. Resolving deltas: 100% (1/1), done. コードを修正してリモートリポジトリにアップロード 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 11.0.1.5 のユーザーを設定 [root@lb01 blog]#git config --global user.email \u0026#34;dev@mail.com\u0026#34; [root@lb01 blog]#git config --global user.name \u0026#34;dev\u0026#34; [root@lb01 blog]#vim a.txt 123 [root@lb01 blog]#git commit -am \u0026#34;123\u0026#34; リモートリポジトリにコミット [root@lb01 blog]#git push -u origin master Counting objects: 5, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 257 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) remote: GitLab: You are not allowed to push code to protected branches on this project.To git@11.0.1.200:dawn/blog.git ! [remote rejected] master -\u0026gt; master (pre-receive hook declined) error: failed to push some refs to \u0026#39;git@11.0.1.200:dawn/blog.git\u0026#39; # master ブランチへのプッシュは許可されていない 他のブランチにプッシュ： 1. dev ブランチを作成 [root@lb01 blog]#git branch dev [root@lb01 blog]#git branch dev * master 2. dev ブランチをリモートにプッシュ [root@lb01 blog]#git push -u origin dev マージリクエスト（MR）\ndev アカウントからマージリクエストを作成 root アカウントでマージを承認し、元の dev ブランチを削除 Web サーバーでコードをダウンロード 1 2 [root@web01 ~]#git clone http://11.0.1.200/dawn/blog.git ユーザー名とパスワードを入力 ","permalink":"https://LMDAWN1127.github.io/ja/posts/gitlab-practice/","summary":"GitLab を自前で導入する実践手順：RPM インストール、コンポーネント、よく使うコマンド、Web UI 設定、SSH 鍵認証、マルチユーザー連携。","title":"GitLab 実践：プライベート導入・SSH 鍵認証・リポジトリ管理"},{"content":"01. Git のインストールとリポジトリの初期化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [root@gitlab ~]#yum install -y git [root@gitlab ~]#git --version git version 1.8.3.1 [root@gitlab ~]#git config --global user.name \u0026#34;dawn\u0026#34; [root@gitlab ~]#git config --global user.email \u0026#34;dawn@mail.com\u0026#34; [root@gitlab ~]#git config --global color.ui true [root@gitlab ~]#cat .gitconfig [user] name = dawn email = dawn@mail.com [color] ui = true [root@gitlab ~]#mkdir dawn [root@gitlab ~]#cd dawn [root@gitlab dawn]#ll total 0 [root@gitlab dawn]#git init Initialized empty Git repository in /root/dawn/.git/ [root@gitlab dawn]#ll total 0 [root@gitlab dawn]#ll -a total 0 drwxr-xr-x 3 root root 18 Jun 11 10:57 . dr-xr-x---. 4 root root 174 Jun 11 10:57 .. drwxr-xr-x 7 root root 119 Jun 11 10:57 .git 02. Git コマンド 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 1. リポジトリの状態を確認する（常にクリーンに保つ） [root@gitlab dawn]#git status # On branch master # # Initial commit # nothing to commit (create/copy files and use \u0026#34;git add\u0026#34; to track) 2. 通常のファイルを作成する [root@gitlab dawn]#touch a.txt 3. 作業ツリーの内容をステージングする [root@gitlab dawn]#git add a.txt # git add . は作業ツリーの全内容をステージング領域に追加する [root@gitlab dawn]#git add . 4. ステージング領域の内容を削除する [root@gitlab dawn]#git rm --cached a.txt rm \u0026#39;a.txt\u0026#39; 5. ステージングしてローカルリポジトリにコミットする [root@gitlab dawn]#git add a.txt [root@gitlab dawn]#git status # On branch master # # Initial commit # # Changes to be committed: # (use \u0026#34;git rm --cached \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # new file: a.txt # # git commit -m にメッセージを付けてローカルリポジトリにコミットする [root@gitlab dawn]#git commit -m \u0026#34;create a.txt\u0026#34; [master (root-commit) b65d348] create a.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a.txt 状態を確認: [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean ファイル作成 touch a.txt ステージング git add a.txt ローカルリポジトリにコミット git commit -m \u0026#34;xxx\u0026#34; 2. git での削除 [root@gitlab dawn]#git rm a.txt rm \u0026#39;a.txt\u0026#39; [root@gitlab dawn]#git status # On branch master # Changes to be committed: # (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # deleted: a.txt # [root@gitlab dawn]#git commit -m \u0026#34;del a.txt\u0026#34; [master 41fc71b] del a.txt 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 a.txt [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean 注意: 作業ツリーのファイルをステージングした後に取り消したい場合は、ステージング領域から削除する [root@gitlab dawn]#touch c.txt [root@gitlab dawn]#git add c.txt [root@gitlab dawn]#git rm --cached c.txt rm \u0026#39;c.txt\u0026#39; 3. 作業ツリーの内容を復元する [root@gitlab dawn]#git reset HEAD b.txt [root@gitlab dawn]#git checkout -- b.txt 4. git での差分確認 git diff 作業ツリーとステージング領域の差分を比較する [root@gitlab dawn]#git diff diff --git a/b.txt b/b.txt index e69de29..ccc3e7b 100644 --- a/b.txt +++ b/b.txt @@ -0,0 +1 @@ +aaaaa git diff --cached ステージング領域とローカルリポジトリの差分を比較する [root@gitlab dawn]#git diff --cached diff --git a/b.txt b/b.txt index e69de29..ccc3e7b 100644 --- a/b.txt +++ b/b.txt @@ -0,0 +1 @@ +aaaaa 5. ファイル名の変更 [root@gitlab dawn]#git mv b.txt b.bak [root@gitlab dawn]#git status # On branch master # Changes to be committed: # (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # renamed: b.txt -\u0026gt; b.bak # [root@gitlab dawn]#git commit -m \u0026#34;newname b.txt--\u0026gt;b.bak\u0026#34; [master 55335a7] newname b.txt--\u0026gt;b.bak 1 file changed, 0 insertions(+), 0 deletions(-) rename b.txt =\u0026gt; b.bak (100%) [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean 6. 任意のスナップショットにロールバックする すべてのスナップショットを表示: [root@gitlab dawn]#git log --oneline ae6585c xx 55335a7 newname b.txt--\u0026gt;b.bak 09ffe53 modifile b.txt 043a297 newfile b.txt 41fc71b del a.txt b65d348 create a.txt [root@gitlab dawn]#ll total 8 -rw-r--r-- 1 root root 6 Jun 11 12:10 b.bak -rw-r--r-- 1 root root 6 Jun 11 12:07 b.txt git reset --hard でロールバックする [root@gitlab dawn]#git reset --hard b65d348 HEAD is now at b65d348 create a.txt [root@gitlab dawn]#ll total 0 -rw-r--r-- 1 root root 0 Jun 11 12:12 a.txt 7. 過去のすべての操作履歴を確認する: [root@gitlab dawn]#git reflog b65d348 HEAD@{0}: reset: moving to b65d348 ae6585c HEAD@{1}: commit: xx 55335a7 HEAD@{2}: commit: newname b.txt--\u0026gt;b.bak 09ffe53 HEAD@{3}: commit: modifile b.txt 043a297 HEAD@{4}: commit: newfile b.txt 41fc71b HEAD@{5}: commit: del a.txt b65d348 HEAD@{6}: commit (initial): create a.txt [root@gitlab dawn]#git reset --hard ae6585c HEAD is now at ae6585c xx [root@gitlab dawn]#ll total 8 -rw-r--r-- 1 root root 6 Jun 11 12:16 b.bak -rw-r--r-- 1 root root 6 Jun 11 12:16 b.txt Git ブランチ 1. ブランチ一覧を表示する（* は現在のブランチ） [root@gitlab dawn]#git branch * master 2. ブランチを作成する [root@gitlab dawn]#git branch dev [root@gitlab dawn]#git branch dev * master 3. dev ブランチに切り替える [root@gitlab dawn]#git checkout dev Switched to branch \u0026#39;dev\u0026#39; [root@gitlab dawn]#git branch * dev master 4. ブランチ上でファイルを作成し、ローカルリポジトリにコミットする [root@gitlab dawn]#touch aa.txt [root@gitlab dawn]#git add . [root@gitlab dawn]#git commit -m \u0026#34;newfile aa.txt\u0026#34; [dev 2694c7f] newfile aa.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 aa.txt 5. ブランチをマージする まず master ブランチに戻る [root@gitlab dawn]#git checkout master Switched to branch \u0026#39;master\u0026#39; [root@gitlab dawn]#git branch dev * master dev ブランチを master にマージする [root@gitlab dawn]#git merge dev Updating ae6585c..2694c7f Fast-forward aa.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 aa.txt 6. 機能を作り終えたらすぐにブランチを削除する（リモートブランチより遅れるため） [root@gitlab dawn]#git branch -d dev Deleted branch dev (was 2694c7f). [root@gitlab dawn]#git branch * master 7. コンフリクトの解決 ---------------------------------- ファイルの内容を変更しても必ずしもマージを妨げるわけではない master ブランチのファイルを編集して bbbbb を追加する [root@gitlab dawn]#vim b.txt aaaaa bbbbb 1 つのコマンドで dev ブランチの作成と切り替えを同時に行える [root@gitlab dawn]#git checkout -b dev Switched to a new branch \u0026#39;dev\u0026#39; [root@gitlab dawn]# [root@gitlab dawn]# [root@gitlab dawn]#git branch * dev master b.txt の内容を編集する [root@gitlab dawn]#vim b.txt aaaaa bbccc ローカルリポジトリにコミットする [root@gitlab dawn]#git add . [root@gitlab dawn]#git commit -m \u0026#34;modifle bbbccc\u0026#34; master ブランチに戻って dev ブランチをマージする [root@gitlab dawn]#git checkout master Switched to branch \u0026#39;master\u0026#39; [root@gitlab dawn]#git branch dev * master [root@gitlab dawn]#cat b.txt aaaaa bbbbb [root@gitlab dawn]#git merge dev Updating f56faba..dc17f6d Fast-forward b.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) [root@gitlab dawn]#cat b.txt aaaaa bbccc ------------------------------------------------------ コンフリクトが発生するケース dev ブランチを作成する [root@gitlab dawn]#git branch dev master ブランチで b.txt の 3 行目を編集する [root@gitlab dawn]#cat b.txt aaaaa iiiii bbbbb [root@gitlab dawn]#git commit -am \u0026#34;modifile b.txt bbbbb\u0026#34; [master ae4ab87] modifile b.txt bbbbb 1 file changed, 1 insertion(+) dev ブランチに切り替えて b.txt の 3 行目を編集する [root@gitlab dawn]#cat b.txt aaaaa iiiii ccccc ローカルリポジトリにコミットする [root@gitlab dawn]#git commit -am \u0026#34;modifile b.txt ccccc\u0026#34; [dev 925c06c] modifile b.txt ccccc 1 file changed, 1 insertion(+) master ブランチに切り替えてブランチをマージする [root@gitlab dawn]#git checkout master Switched to branch \u0026#39;master\u0026#39; [root@gitlab dawn]#git branch dev * master [root@gitlab dawn]#git merge dev Auto-merging b.txt CONFLICT (content): Merge conflict in b.txt Automatic merge failed; fix conflicts and then commit the result. ファイルを確認すると競合が表示される [root@gitlab dawn]#cat b.txt aaaaa iiiii \u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt;\u0026lt; HEAD bbbbb ======= ccccc \u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u0026gt; dev 手動で競合を解決し、片方だけ、あるいは両方を残す [root@gitlab dawn]#vim b.txt aaaaa iiiii bbbbb ccccc [root@gitlab dawn]#git commit -am \u0026#34;merge dev\u0026#34; [master 325eef2] merge dev [root@gitlab dawn]# [root@gitlab dawn]# [root@gitlab dawn]#git status # On branch master nothing to commit, working directory clean [root@gitlab dawn]#cat b.txt aaaaa iiiii bbbbb ccccc マージ後に dev ブランチを削除する [root@gitlab dawn]#git branch -d dev Deleted branch dev (was 925c06c). ","permalink":"https://LMDAWN1127.github.io/ja/posts/git-practice-notes/","summary":"インストールから基本コマンド、ブランチ運用、コンフリクト解決までを網羅した Git 実践メモ。","title":"Git 実践ノート：インストール・基本コマンド・ブランチ管理"},{"content":"1. ログインユーザー数を取得する 1 2 3 4 5 6 7 [root@web02 ~]#w 17:44:18 up 1:17, 2 users, load average: 0.01, 0.02, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 11.0.1.1 16:31 11:46 0.07s 0.07s -bash root pts/1 11.0.1.52 17:07 2.00s 0.04s 0.00s w [root@web02 ~]#w|awk \u0026#39;NR==1{print $4}\u0026#39; 2 2. Zabbix の監視項目として定義する 1 2 3 4 5 6 7 [root@web02 ~]# cat /etc/zabbix/zabbix_agentd.d/system.conf UserParameter=login_number,w|awk \u0026#39;NR==1{print $4}\u0026#39; # zabbix_agentd -p で項目の文法チェックができます [root@web02 ~]#zabbix_agentd -p|grep login_number login_number [t|2] # クライアントを再起動 [root@web02 ~]# systemctl restart zabbix-agent.service 3. Zabbix サーバー側で収集・監視する サーバーからコマンドラインで、監視項目を通じてユーザー定義の値が取得できるかテストします。\n1 2 3 4 # zabbix-get コマンドをインストール [root@zabbix ~]# yum -y install zabbix-get [root@zabbix ~]#zabbix_get -s 172.16.1.8 -k login_number 2 Web ページで監視項目を追加する\n監視項目を確認する\n4. TCP 22 ポートの生存を監視する 監視したい情報に合わせてキー値を選択します。\nTCP ポートが LISTEN 状態かどうかを確認します。戻り値: 0 - 待ち受けなし; 1 - 待ち受け中。\nweb02 の sshd サービスを停止する\n1 [root@web02 ~]# systemctl stop sshd 5. 表示用のカスタム値マッピングを設定する 値マッピングを適用する\n6. サーバーメモリ使用率のカスタム監視 手順 1: カスタム項目を定義し、空き率を取得する\n1 2 3 4 5 6 [root@web02 ~]# cat /etc/zabbix/zabbix_agentd.d/system.conf UserParameter=login_number,w|awk \u0026#39;NR==1{print $4}\u0026#39; UserParameter=mem_free,free|awk \u0026#39;NR==2{print $NF/$2*100}\u0026#39; [root@web02 ~]# systemctl restart zabbix-agent.service [root@web02 ~]#zabbix_agentd -p|grep mem_free mem_free [t|79.8753] 手順 2: サーバー側でキー値の取得をテストし、監視項目を追加する\n1 2 [root@zabbix ~]#zabbix_get -s 172.16.1.8 -k mem_free 79.9775 7. 空きメモリにトリガーを設定する 空きメモリ率が 20% を下回った場合にアラートを発報します。\nテスト: swap パーティションを無効にする\n1 [root@web02 ~]# swapoff -a dd でストレステストを実行しメモリを消費する\n1 [root@web02 ~]# dd if=/dev/zero of=/dev/null bs=1200M count=2048 8. 複数条件トリガーを設定する 両方の条件が同時に満たされた場合にのみアラートを発報します。\nswap 空き率を追加する\n1 2 3 4 [root@web02 ~]# cat /etc/zabbix/zabbix_agentd.d/system.conf UserParameter=login_number,w|awk \u0026#39;NR==1{print $4}\u0026#39; UserParameter=mem_free,free|awk \u0026#39;NR==2{print $NF/$2*100}\u0026#39; UserParameter=swap_free,free -m|awk \u0026#39;NR==3{print $3/$2*100}\u0026#39; トリガー設定を変更する\nその後、再度 dd ストレステストを実行して結果を確認します。\n","permalink":"https://LMDAWN1127.github.io/ja/posts/zabbix-custom-monitor/","summary":"Zabbix カスタム監視の実践 — UserParameter でログインユーザー数やメモリ空き率などの独自メトリクスを収集し、zabbix_get で検証、Web UI で監視項目・値マッピング・トリガー（複数条件トリガー含む）を追加してカスタムアラートを実現します。","title":"Zabbix カスタム監視"},{"content":"企業の Zabbix 高負荷シナリオでの使用を想定しています。\n1. 独立したデータベースサーバー (11.0.1.52) を用意し MariaDB をインストールする 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@db02 ~]#yum -y install mariadb-server [root@db02 ~]#systemctl enable mariadb --now [root@db02 ~]#mysql Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 2 Server version: 5.5.68-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [(none)]\u0026gt; create database zabbix character set utf8 collate utf8_bin; Query OK, 1 row affected (0.02 sec) MariaDB [(none)]\u0026gt; create user \u0026#39;zabbix\u0026#39;@\u0026#39;%\u0026#39; identified by \u0026#39;zabbix\u0026#39;; Query OK, 0 rows affected (0.10 sec) MariaDB [(none)]\u0026gt; grant all privileges on zabbix.* to \u0026#39;zabbix\u0026#39;@\u0026#39;%\u0026#39;; Query OK, 0 rows affected (0.00 sec) 2. Zabbix サーバーから zabbix データベースをエクスポートし、新しいデータベースへインポートする 1 2 [root@zabbix ~]# mysqldump -uroot -B zabbix \u0026gt; zabbix.sql [root@zabbix ~]# cat zabbix.sql |mysql -h 172.16.1.52 -uzabbix -pzabbix zabbix 3. Web UI のデータベース接続を設定する 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@zabbix ~]# systemctl stop mariadb [root@zabbix ~]# cat /etc/zabbix/web/zabbix.conf.php \u0026lt;?php // Zabbix GUI configuration file. global $DB; $DB[\u0026#39;TYPE\u0026#39;] = \u0026#39;MYSQL\u0026#39;; $DB[\u0026#39;SERVER\u0026#39;] = \u0026#39;172.16.1.52\u0026#39;; $DB[\u0026#39;PORT\u0026#39;] = \u0026#39;0\u0026#39;; $DB[\u0026#39;DATABASE\u0026#39;] = \u0026#39;zabbix\u0026#39;; $DB[\u0026#39;USER\u0026#39;] = \u0026#39;zabbix\u0026#39;; $DB[\u0026#39;PASSWORD\u0026#39;] = \u0026#39;zabbix\u0026#39;; [root@zabbix ~]# grep ^DB /etc/zabbix/zabbix_server.conf DBHost=172.16.1.52 DBName=zabbix DBUser=zabbix DBPassword=zabbix 4. サービスを再起動する 1 [root@zabbix ~]# systemctl restart zabbix-server httpd ","permalink":"https://LMDAWN1127.github.io/ja/posts/zabbix-split-database/","summary":"企業の Zabbix 高負荷シナリオ向け — Zabbix サーバーから専用の MariaDB サーバー (11.0.1.52) へデータベースを分割します。データベース作成と権限付与、データのエクスポート/インポート、Web UI と Server のデータベース接続設定の変更、そしてサービスの再起動まで。","title":"Zabbix データベースの分割"},{"content":"1. zabbix-agent クライアントをインストールする — サーバー (11.0.1.8) を用意 1 2 3 4 5 6 7 8 リポジトリを設定します： [root@web02 ~]# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm サーバー側の yum リポジトリをクライアントへ同期します： [root@zabbix ~]#scp /etc/yum.repos.d/CentOS-SCLo-scl.repo root@172.16.1.8:/etc/yum.repos.d/CentOS-SCLo-scl.repo [root@zabbix ~]#scp /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo root@172.16.1.8:/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo [root@zabbix ~]#scp /etc/yum.repos.d/zabbix.repo root@172.16.1.8:/etc/yum.repos.d/zabbix.repo インストール時にパッケージ競合が発生した場合： [root@web02 ~]# yum -y install centos-release-scl 2. zabbix-agent にサーバー情報を設定し、起動する 1 2 3 4 5 6 [root@web02 ~]# yum -y install zabbix-agent [root@web02 ~]# vim /etc/zabbix/zabbix_agentd.conf Server=172.16.1.71 ServerActive=172.16.1.71 Hostname=web02 [root@web02 ~]# systemctl enable zabbix-agent --now 3. Zabbix から web02 を監視する 4. web02 の監視設定完了 ","permalink":"https://LMDAWN1127.github.io/ja/posts/zabbix-monitor-server/","summary":"対象サーバー (web02, 11.0.1.8) に Zabbix エージェントを導入し、Zabbix サーバーへ紐づけて、Web UI から監視を開始する手順です。","title":"Zabbix でサーバー情報を監視する"},{"content":"1. リポジトリを設定する 1 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm 2. zabbix-server と zabbix-agent をインストールする 1 yum -y install zabbix-server-mysql zabbix-agent 3. SCL リポジトリをインストールする（バージョン競合の解決） 1 [root@zabbix ~]# yum -y install centos-release-scl 4. フロントエンドリポジトリを有効化する 1 2 3 4 5 [root@zabbix ~]# vim /etc/yum.repos.d/zabbix.repo [zabbix-frontend] ... enabled=1 ... 5. CentOS-SCLo-scl.repo / CentOS-SCLo-scl-rh.repo の壊れた mirrorlist を Aliyun の baseurl に置き換える 1 2 3 4 5 6 7 8 9 10 [root@zabbix yum.repos.d]#vim CentOS-SCLo-scl-rh.repo [centos-sclo-rh] ... baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh ... [root@zabbix yum.repos.d]#vim CentOS-SCLo-scl.repo [centos-sclo-sclo] ... baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo ... 6. PHP/Apache フロントエンドをインストールする 1 [root@zabbix ~]# yum -y install zabbix-web-mysql-scl zabbix-apache-conf-scl 7. MariaDB データベースをインストールする 1 2 3 [root@zabbix ~]# yum -y install mariadb-server データベースを起動します： [root@zabbix ~]#systemctl enable mariadb --now 8. Zabbix データベースを作成する 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [root@zabbix ~]#mysql -uroot Welcome to the MariaDB monitor. Commands end with ; or \\g. Your MariaDB connection id is 7 Server version: 5.5.68-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type \u0026#39;help;\u0026#39; or \u0026#39;\\h\u0026#39; for help. Type \u0026#39;\\c\u0026#39; to clear the current input statement. MariaDB [(none)]\u0026gt; create database zabbix character set utf8 collate utf8_bin; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]\u0026gt; create user zabbix@localhost identified by \u0026#39;zabbix\u0026#39;; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]\u0026gt; grant all privileges on zabbix.* to zabbix@localhost; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]\u0026gt; set global log_bin_trust_function_creators = 1; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]\u0026gt; quit Bye 9. データベースを初期化する（Zabbix 起動前に必要なスキーマをインポート） 1 2 3 4 5 [root@zabbix ~]# zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -p zabbix # zabbix のパスワードの入力を求められます [root@zabbix ~]# mysql -uroot MariaDB [(none)]\u0026gt; set global log_bin_trust_function_creators = 0; quit 10. Zabbix のデータベース接続を設定する 1 2 3 4 [root@zabbix ~]# egrep ^DB /etc/zabbix/zabbix_server.conf DBName=zabbix DBUser=zabbix DBPassword=zabbix # コメントを外してパスワードを設定 11. タイムゾーンを設定する 1 2 [root@zabbix ~]# tail -1 /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf php_value[date.timezone] = Asia/Shanghai 12. サービス（server、agent、httpd、php）を起動し、起動時有効化する 1 [root@zabbix ~]# systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm --now 13. Zabbix Web UI に 11.0.1.71/zabbix でアクセスする 14. Zabbix のインストール完了 15. 中国語表示に切り替え、フォントを再設定する Windows のフォントを見つけて、Zabbix のフォントディレクトリにコピーします。\nWindows フォントの保存場所：\nいずれかのフォントをアップロードし、名前を変更します：\n1 2 3 4 5 6 7 8 9 10 [root@zabbix ~]#cd /usr/share/zabbix/assets/fonts/ [root@zabbix fonts]#ls graphfont.ttf simhei.ttf # アップロードしたフォント [root@zabbix fonts]#rm -f graphfont.ttf # 元のフォントを削除 [root@zabbix fonts]#ln -s /usr/share/zabbix/assets/fonts/simhei.ttf graphfont.ttf # アップロードしたフォントにリンク [root@zabbix fonts]#chmod 644 simhei.ttf [root@zabbix fonts]#ll total 9520 lrwxrwxrwx 1 root root 41 Sep 23 01:19 graphfont.ttf -\u0026gt; /usr/share/zabbix/assets/fonts/simhei.ttf -rw-r--r-- 1 root root 9745792 Sep 23 01:18 simhei.ttf ","permalink":"https://LMDAWN1127.github.io/ja/posts/zabbix-install/","summary":"CentOS 7 に Zabbix 5.0 をインストールする手順を解説。リポジトリ設定、サーバー/エージェント/フロントエンドの導入、MariaDB 構築、スキーマのインポート、Web UI の中国語化とフォント設定まで。","title":"Zabbix のインストールとデプロイ"},{"content":"計画は以下の通りです：\nMaster ノード： ホスト名： master IP アドレス：192.168.8.30\nWorker01 ノード： ホスト名： node1 IP アドレス：192.168.8.31\nWorker02 ノード： ホスト名： node2 IP アドレス：192.168.8.32\n3 つのノードすべてで以下の手順を完了し、3 つのノードの時刻が一致していることを確認してください。\n1. ファイアウォールと SELinux を無効にする 1 2 3 4 [root@master ~]# systemctl disable firewalld.service --now [root@master ~]# vim /etc/selinux/config SELINUX=disabled [root@master ~]# setenforce 0 2. スワップを無効にする 1 2 [root@master ~]# sed -i \u0026#39;/swap/s/^/#/\u0026#39; /etc/fstab [root@master ~]# swapoff -a 3. システムパラメータの設定とカーネルモジュールのロード 1 2 3 4 5 6 7 8 9 10 11 12 [root@master ~]# cat \u0026gt; /etc/modules-load.d/k8s.conf \u0026lt;\u0026lt; EOF overlay br_netfilter EOF [root@master ~]# modprobe overlay [root@master ~]# modprobe br_netfilter [root@master ~]# cat \u0026gt; /etc/sysctl.d/k8s.conf \u0026lt;\u0026lt; EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF [root@master ~]# sysctl --system 4. コンテナランタイム（Containerd）のインストール Kubernetes v1.30 ではコンテナランタイムとして Containerd の使用が推奨されています：\n1 [root@master ~]# yum -y remove runc OS 同梱の yum リポジトリファイルを削除します：\n1 [root@master ~]# rm -rf /etc/yum.repos.d/Cent*.repo ローカル yum リポジトリを設定します：\n1 2 3 4 5 6 7 8 9 10 11 12 [root@master ~]# mount /dev/cdrom /media/ [root@master ~]# cat /etc/fstab | grep iso9660 /dev/cdrom\t/media\tiso9660 defaults 0 0 [root@master ~]# cat /etc/yum.repos.d/dvd.repo [BaseOS] name=BaseOS baseurl=file:///media/BaseOS gpgcheck=0 [AppStream] name=AppStream baseurl=file:///media/AppStream gpgcheck=0 Containerd を設定します：\n1 2 [root@master ~]# yum install -y yum-utils [root@master ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo containerd.io をインストールします：\n1 2 3 4 5 6 7 8 9 10 [root@master ~]# yum install -y containerd.io # 設定ファイルを生成して編集する [root@master ~]# mkdir -p /etc/containerd [root@master ~]# containerd config default \u0026gt; /etc/containerd/config.toml # systemd cgroup ドライバを使用するよう設定を編集する #sed -i \u0026#39;s/SystemdCgroup = false/SystemdCgroup = true/g\u0026#39; /etc/containerd/config.toml # イメージアクセラレーションを設定（任意） #sed -i \u0026#39;s|registry.k8s.io|registry.aliyuncs.com/google_containers|g\u0026#39; /etc/containerd/config.toml # 起動してブート時に有効化する #systemctl enable --now containerd 5. Kubernetes のインストールと設定 1 2 3 4 5 6 7 [root@master yum.repos.d]# cat kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/ enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm/repodata/repomd.xml.key 指定バージョンの Kubernetes コンポーネントをインストールします：\n1 2 3 [root@master ~]# yum install -y kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 --disableexcludes=kubernetes # kubelet を起動する [root@master ~]# systemctl enable --now kubelet 6. Kubernetes の初期化 注意：すべてのノードで上記の設定が完了したら、以下の手順は master ノードでのみ実行してください。\n1 2 3 4 5 [root@master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=172.16.0.0/16 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.30.0 --control-plane-endpoint=\u0026#34;192.168.8.30:6443\u0026#34; --upload-certs # kubectl を設定する [root@master ~]# mkdir -p $HOME/.kube [root@master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@master ~]# chown $(id -u):$(id -g) $HOME/.kube/config 7. ワーカーノードを Kubernetes クラスタに参加させる 以下のコマンドをワーカーノードで実行します。注意：ノードごとにトークンと CA 証明書ハッシュが異なる場合があります。お使いのシステムの指示に従ってください。証明書の有効期限が切れている場合もあります。その場合は kubeadm token create --print-join-command で参加コマンドを再生成してください。\n1 2 [root@node1 ~]# kubeadm join 192.168.8.30:6443 --token yfjrsi.60lmqgzobp0b8al3 --discovery-token-ca-cert-hash sha256:f4e3c924918545abfd8148e71a377e086d591c6a59856a496b4b33e0987d9c18 [root@node2 ~]# kubeadm join 192.168.8.30:6443 --token yfjrsi.60lmqgzobp0b8al3 --discovery-token-ca-cert-hash sha256:f4e3c924918545abfd8148e71a377e086d591c6a59856a496b4b33e0987d9c18 8. master ノードへの Calico ネットワークプラグインのインストール 1 2 # Calico ネットワークプラグインをインストールする [root@master ~]# kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml 注意：周知の理由により、Calico イメージのダウンロードに失敗する場合があります。\n当該マニフェストファイルを修正したので、master ノードにダウンロードして適用してください：\nこのファイルは百度網盤（Baidu Netdisk）にアップロードしてあります。ダウンロードリンク：https://pan.baidu.com/s/1BPCFxv0kE0KWb04Qsgy71g （抽出コード：s44k）\n1 [root@master ~]# kubectl apply -f /root/calico-ucloud.yaml インストール完了後、以下を実行します：\n1 2 3 4 5 [root@master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION master Ready control-plane 65m v1.30.13 node1 Ready \u0026lt;none\u0026gt; 62m v1.30.0 node2 Ready \u0026lt;none\u0026gt; 62m v1.30.0 上記の結果が表示されれば、Kubernetes のインストールは完了です。\n9. 補足 各ノードで以下のコマンドを実行します：\n1 2 3 4 5 kubectl completion bash \u0026gt; /etc/bash_completion.d/kubectl source /etc/bash_completion.d/kubectl vim /root/.bashrc alias docker=\u0026#39;crictl\u0026#39; source /root/.bashrc 補足：\nkubectl の補完：上の 2 行は kubectl の補完スクリプトを /etc/bash_completion.d/ に書き出します。ただしその前提として、システムに bash-completion パッケージがインストールされていること（yum install -y bash-completion や apt install -y bash-completion）が必要です。インストールされていないと該当ディレクトリが存在せず、補完は機能しません。さらに kubectl 自体もこの 2 行を実行して初めて補完が有効になります（Kubernetes は別途この設定が必要です）。 docker エイリアス：Kubernetes が containerd ランタイムに切り替わったため、コンテナ管理コマンドは docker から crictl に変わります。ここで docker を crictl にエイリアスするのは、docker コマンドに慣れたユーザーの操作性を考慮し、これまでの操作感を維持するためです。 # docker images を実行した際に、以下のエラーが発生した場合：\nKubernetes に以下の警告が表示された場合の解決方法は次の通りです。\nWARN[0000] image connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead.\nこの警告は、使用しているコンテナランタイムクライアント（crictl や kubelet など）がデフォルトのエンドポイント設定を使用しており、それが非推奨となっているため明示的に設定する必要があることを示しています。解決手順は以下の通りです：\n1 2 3 4 5 6 7 cat \u0026gt; /etc/crictl.yaml \u0026lt;\u0026lt; EOF runtime-endpoint: unix:///run/containerd/containerd.sock # 使用するコンテナランタイムに合わせて選択 image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false pull-image-on-create: false EOF 補足：\nContainerd を使用する場合、エンドポイントは unix:///run/containerd/containerd.sock です。\nCRI-O を使用する場合、エンドポイントは unix:///run/crio/crio.sock です。\n備考：任意。\nKubernetes を手動でインストールした場合、デフォルトではデータ転送に iptables が使用されます。大規模なシナリオでは、IPVS モードへの変更を推奨します。インストール完了後に IPVS モードに変更する手順は以下の通りです：\n1. 全ノードに ipvsadm パッケージをインストールする 2. 全ノードでモジュールをロードする 1 2 3 4 5 6 7 cat \u0026gt; /etc/modules-load.d/ipvs.conf \u0026lt;\u0026lt; EOF ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack EOF 3. kube-proxy ConfigMap を編集する 1 kubectl edit cm kube-proxy -n kube-system 開いたエディタで、以下のセクションを探して変更します：\n1 2 3 4 5 6 7 apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: \u0026#34;ipvs\u0026#34; # \u0026#34;iptables\u0026#34; から \u0026#34;ipvs\u0026#34; に変更 ipvs: scheduler: \u0026#34;rr\u0026#34; # ロードバランシングアルゴリズム： rr|wrr|lc 4. kube-proxy Pod を強制再起動する すべての kube-proxy Pod を削除して再作成をトリガーします：\n1 #kubectl delete pods -n kube-system -l k8s-app=kube-proxy 5. 新しい Pod が正常に動作していることを確認する 1 2 #kubectl get pods -n kube-system -l k8s-app=kube-proxy # すべての Pod が Running 状態であること 6. IPVS 設定が有効になったことを確認する 1 2 3 4 5 [root@master ~]# ipvsadm -L -n TCP 192.168.8.30:30080 rr -\u0026gt; 10.244.104.3:80 Masq 1 0 0 -\u0026gt; 10.244.104.4:80 Masq 1 0 0 -\u0026gt; 10.244.166.132:80 Masq 1 0 0 ","permalink":"https://LMDAWN1127.github.io/ja/posts/k8s-v1.30-manual-deploy/","summary":"kubeadm を用いて Kubernetes v1.30 クラスタを手動でデプロイする手順を解説します。ファイアウォール/SELinux、スワップ、カーネルモジュール、Containerd、kubeadm init、ワーカー参加、Calico、IPVS 追加まで網羅。","title":"Kubernetes v1.30 クラスタを手動デプロイする（kubeadm 方式）"},{"content":" 本記事ではKVM仮想化技術を体系的に紹介し、発展の歴史、デプロイ方法、仮想マシン管理、ネットワークモードの構成、コマンドラインによる自動インストールをカバーします。すべてのコマンドはCentOS/RHEL環境で検証済みです。\nI. KVMの発展の歴史 KVM（Kernel-based Virtual Machine）は、今日のクラウドコンピューティング分野における主流の仮想化技術です。その発展の脈絡を理解することで、業界がなぜ最終的にKVMを選択したのかを理解できます。\n仮想化技術は大きく二つのカテゴリに分けられます：クローズドソース仮想化（例：VMware、Microsoft Hyper-V）とオープンソース仮想化（例：Xen、KVM）。\n初期のオープンソース仮想化の代表はXenでした。AWSとAlibaba Cloudは初期にどちらもXen方式を採用していました。CitrixのXenServerおよびデスクトップクラウド製品FusionAccess（Citrix XenDesktopに対応）もXenをベースにしていました。HuaweiのFusionComputeも6.3バージョン以前はXenを使用していました。\n主なマイルストーンは以下の通りです：\n2008年：Red HatがKVMを買収し、RHEL 5.4で正式にKVMをリリースしました（RHEL 5.0にはXenが搭載されていました）。 2010年：OpenStackプロジェクトが誕生しました。Red HatはIBM、Dell、VMware、Cisco、HPなどと共にKVMオープンソースコミュニティを支援し、オープンソースソフトウェア財団の下でエコシステムを構築しました。同時期にCitrixはCloudStackコミュニティを推進していました。 2014年：RHEL 5.11がリリースされました（RHEL 5.xシリーズのライフサイクル終了、7年間の技術サポート提供、KVMへの無料アップグレードが可能）。 2017年前後：AWSがKVMベースのNitroプラットフォームインスタンスを発表し、Alibaba Cloudおよび世界中の多くのベンダーがKVMを全面的に採用しました。 今日、主要なクラウドサービスプロバイダーの仮想化基盤は基本的にKVMです。HuaweiのFusionCompute 6.3もXenからKVMに切り替えました。2019年にIBMが約340億ドルでRed Hatを買収し、Ansible、GlusterFS、CephなどのRed Hatエコシステムプロジェクトがその傘下に入りました。これはこの技術路線の価値をさらに裏付けるものです。\nII. KVMとは KVMはKernel-based Virtual Machineの略です。その核心的な特徴は以下の通りです：\nカーネルのアップグレードが不要：システム自体のカーネルを直接再利用し、各仮想マシンは一つのプロセスとして実行されます。 軽量な仮想化プラットフォーム：従来の方式に比べてより軽量で効率的です。 統合管理：Xen/KVM仮想化プラットフォームはどちらも統合管理プラットフォームとコマンドラインツールを提供しています。 III. KVMのデプロイ 1. KVM必要パッケージのインストール 前提条件：物理マシンのBIOSで仮想化サポートVT-xを有効にします（ほとんどのコンピュータではデフォルトで有効）。VMware内でネストしてインストールする場合は、VMwareの設定でもVT-xサポートを有効にする必要があります。\n推奨リソース構成：CPU 4コア、メモリ4GB。\n1 2 [root@cloud ~]# yum -y groupinstall \u0026#34;Virtualization*\u0026#34; [root@cloud ~]# systemctl restart libvirtd.service 2. グラフィカルな仮想マシンインストール 本実習ではグラフィカルツールvirt-managerを使用して仮想マシンを作成・インストールします。\n注意：グラフィカルウィザードの操作手順は本記事ではスクリーンショットで示しません。本文はコマンドライン操作を主とし、グラフィカルインターフェースは指示に従ってクリックすれば完了します。また、「ホストマシン」とはKVM仮想マシンを実行するマシンを指します。本実習はVMware内でネスト仮想化を行うため、ここでのホストマシンは物理マシンではなくVMware仮想マシンです。\nまずシステムインストールイメージを準備します：/isosディレクトリを作成し、CentOS 8.4のISOファイルをコピーします。\n1 [root@cloud ~]# mkdir /isos グラフィカル管理インターフェースを起動します：\n1 [root@cloud ~]# virt-manager インターフェースで新規仮想マシンの作成をクリックし、/isosに配置したISOをインストールソースとして選択し、ウィザードに従ってCPU、メモリ、ディスクを構成すればインストールが完了します。インストールされた仮想マシンのディスクファイルはデフォルトで/var/lib/libvirt/images/ディレクトリにserver1.qcow2のような名前で保存されます：\n1 2 3 [root@cloud ~]# cd /var/lib/libvirt/images/ [root@cloud images]# ls server1.qcow2 3. ディスクの作成 前のステップのグラフィカルインストール時にvirt-managerが自動的にディスクを作成します。ここでは手動作成の方法を紹介します。これは後でクラウドイメージの作成や仮想マシンへのディスク追加で使用します。qemu-imgを使用してqcow2形式のディスクを作成します：\n1 [root@cloud ~]# qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/server1.qcow2 10g ヒント：この方法でクラウドイメージを作成する場合、容量が小さいほど作成速度が速くなります。イメージを最小化する方法を研究することをお勧めします。通常、システムディスクは高い性能を要求しません。本当の性能のボトルネックはデータディスクにあります。\n4. ブリッジモードの作成（アップリンク付き仮想スイッチ） ネットワーク構成ディレクトリに移動し、既存のネットワークインターフェースをベースにブリッジ構成をコピーします：\n1 2 [root@cloud ~]# cd /etc/sysconfig/network-scripts/ [root@cloud network-scripts]# cp ifcfg-ens33 ifcfg-br0 ブリッジインターフェースifcfg-br0の編集：\n1 [root@cloud network-scripts]# cat ifcfg-br0 1 2 3 4 5 6 7 8 TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=192.168.8.99 PREFIX=24 GATEWAY=192.168.8.254 DNS1=192.168.8.254 物理インターフェースifcfg-ens33をbr0にブリッジするよう編集：\n1 [root@cloud network-scripts]# cat ifcfg-ens33 1 2 3 4 5 TYPE=Ethernet NAME=ens33 DEVICE=ens33 ONBOOT=yes BRIDGE=br0 ネットワーク構成を再読み込みし、接続を再起動します：\n1 2 3 [root@cloud ~]# nmcli connection reload [root@cloud ~]# nmcli connection down ens33 ; nmcli connection up ens33 [root@cloud ~]# nmcli connection down br0 ; nmcli connection up br0 5. クラウドイメージの作成 要件：カスタムクラウドマシンイメージを作成します。\nKVM仮想マシンのデプロイ完了後、仮想マシンに入って必要なソフトウェアをインストールします：\nローカルyumリポジトリの構成 必要なパッケージのインストール： 1 # yum -y install net-tools vim-enhanced bash-completion cloud-init /etc/cloud/cloud.cfg構成ファイルを編集し、実際の要件に応じてパラメータを調整 /etc/ssh/ssh_host*を削除 init 0でシャットダウン 最後にイメージを圧縮します：\n1 [root@cloud images]# qemu-img convert -c -O qcow2 /var/lib/libvirt/images/server1.qcow2 /isos/server1.qcow2 IV. KVMの管理 virsh対話型インターフェースに入ります：\n1 [root@cloud ~]# virsh 主な仮想マシン管理コマンドは以下の通りです。\nすべての仮想マシンの一覧表示：\n1 2 3 4 [root@cloud ~]# virsh list --all Id Name State ------------------------- - server1 shut off 仮想マシンの起動 / シャットダウン / 強制終了 / 再起動：\n1 2 3 4 [root@cloud ~]# virsh start server1 [root@cloud ~]# virsh shutdown server1 [root@cloud ~]# virsh destroy server1 [root@cloud ~]# virsh reboot server1 6. 仮想マシンコンソールインターフェースへのアクセス KVM仮想マシンに入り、仮想マシンに仮想コンソールを追加することで、ホストマシンからコンソール方式で仮想マシンにアクセスできます。\n仮想マシン内でgrub構成を編集：\n1 [root@VM1 ~]# vim /etc/default/grub GRUB_CMDLINE_LINUXの末尾にconsole=ttyS0を追加：\n1 GRUB_CMDLINE_LINUX=\u0026#34;crashkernel=auto resume=UUID=94e88e69-fad6-4d1f-99cf-0ba83cc793b5 rhgb quiet console=ttyS0\u0026#34; grub構成を再生成し再起動：\n1 2 [root@VM1 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg [root@VM1 ~]# reboot ホストマシンからコンソールに接続：\n1 [root@cloud ~]# virsh console server1 コンソールを終了するショートカットキーはCtrl + ]です。\n7. 構成による仮想マシンへのディスク追加 (1) ディスクファイルの作成：\n1 [root@cloud images]# qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/disk2.qcow2 5g (2) 構成ファイルでディスクを追加：\n1 [root@cloud ~]# vim /etc/libvirt/qemu/server1.xml 構成に以下のdiskセクションを追加：\n1 2 3 4 5 6 \u0026lt;disk type=\u0026#39;file\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;qcow2\u0026#39;/\u0026gt; \u0026lt;source file=\u0026#39;/var/lib/libvirt/images/disk2.qcow2\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vdb\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x07\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; サービスを再起動し仮想マシンを起動：\n1 2 3 [root@cloud ~]# systemctl restart libvirtd.service [root@cloud ~]# virsh start server1 [root@cloud ~]# virsh console server1 KVM仮想マシン内でディスクを確認：\n1 2 3 [root@localhost ~]# fdisk -l /dev/vda /dev/vdb 比較：Xen仮想化ではディスクデバイス名は/dev/xvda、/dev/xvdbです。\n8. KVM仮想マシンの迅速な作成 既存の仮想マシンのXML構成をコピーして迅速に作成：\n1 2 3 4 [root@cloud qemu]# cp server1.xml server2.xml [root@cloud qemu]# uuidgen f3ccabc3-ca4c-41f2-8d6f-e99077c24eeb [root@cloud qemu]# vim server2.xml name、uuid、ディスクパス、MACアドレスなどの主要パラメータを変更：\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \u0026lt;domain type=\u0026#39;kvm\u0026#39;\u0026gt; \u0026lt;name\u0026gt;server2\u0026lt;/name\u0026gt; \u0026lt;uuid\u0026gt;f3ccabc3-ca4c-41f2-8d6f-e99077c24eeb\u0026lt;/uuid\u0026gt; \u0026lt;metadata\u0026gt; \u0026lt;disk type=\u0026#39;file\u0026#39; device=\u0026#39;disk\u0026#39;\u0026gt; \u0026lt;driver name=\u0026#39;qemu\u0026#39; type=\u0026#39;qcow2\u0026#39;/\u0026gt; \u0026lt;source file=\u0026#39;/isos/server1.qcow2\u0026#39;/\u0026gt; \u0026lt;target dev=\u0026#39;vda\u0026#39; bus=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x04\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/disk\u0026gt; \u0026lt;interface type=\u0026#39;bridge\u0026#39;\u0026gt; \u0026lt;mac address=\u0026#39;52:54:00:96:f6:a2\u0026#39;/\u0026gt; \u0026lt;source bridge=\u0026#39;br0\u0026#39;/\u0026gt; \u0026lt;model type=\u0026#39;virtio\u0026#39;/\u0026gt; \u0026lt;address type=\u0026#39;pci\u0026#39; domain=\u0026#39;0x0000\u0026#39; bus=\u0026#39;0x01\u0026#39; slot=\u0026#39;0x00\u0026#39; function=\u0026#39;0x0\u0026#39;/\u0026gt; \u0026lt;/interface\u0026gt; サービスを再起動し新しい仮想マシンを起動：\n1 2 3 [root@cloud ~]# systemctl restart libvirtd.service [root@cloud ~]# virsh start server2 [root@cloud ~]# virsh list --all V. KVMネットワーク構成 KVMには一般的に3つのネットワークモードがあります：NATモード、ホストオンリーモード（Host-Only）、ブリッジモード。\n1. NATモード iptablesのアドレスマスカレードでNATを実現します：\n1 # iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE またはSNATでソースアドレスを指定：\n1 # iptables -t nat -A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j SNAT --to-source 192.168.8.99 NATルールの確認：\n1 [root@cloud ~]# iptables -t nat -nL デフォルトのネットワーク構成ファイルは/etc/libvirt/qemu/networksにあります：\n1 2 3 [root@cloud networks]# pwd /etc/libvirt/qemu/networks [root@cloud networks]# vim default.xml 2. ホストオンリーモード ホストオンリーモードでは、仮想マシンはホストマシンとのみ通信でき、外部ネットワークにはアクセスできません。\n3. KVM仮想マシンからのインターネットアクセスの有効化 (1) VMwareホストマシンにインターネットアクセス可能なネットワークインターフェースを追加します。\n(2) ホストマシンのOSに入り、デュアルブリッジを構成します。\nifcfg-br0（内部ネットワークブリッジ）：\n1 2 3 4 5 6 TYPE=Bridge NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=192.168.8.99 PREFIX=24 ifcfg-br1（外部ネットワークブリッジ、DHCP）：\n1 2 3 4 5 TYPE=Bridge NAME=br1 DEVICE=br1 ONBOOT=yes BOOTPROTO=dhcp ifcfg-ens33をbr0にブリッジ：\n1 2 3 4 5 TYPE=Ethernet NAME=ens33 DEVICE=ens33 ONBOOT=yes BRIDGE=br0 ifcfg-ens37をbr1にブリッジ：\n1 2 3 4 5 TYPE=Ethernet NAME=ens37 DEVICE=ens37 ONBOOT=yes BRIDGE=br1 サービスを再起動し仮想マシンをシャットダウン：\n1 2 3 4 5 [root@cloud ~]# systemctl restart libvirtd.service [root@cloud ~]# virsh shutdown server1 Domain server1 is being shutdown [root@cloud ~]# virsh shutdown server2 Domain server2 is being shutdown KVM内のserver1仮想マシンのネットワークインターフェースをbr1にブリッジするよう変更し、VM1内でIP取得方式をDHCPに変更：\n1 2 3 4 5 6 7 8 9 10 11 [root@VM1 ~]# nmcli connection modify enp1s0 ipv4.method auto autoconnect yes [root@VM1 ~]# nmcli connection down enp1s0 ; nmcli connection up enp1s0 [root@VM1 ~]# ifconfig enp1s0: flags=4163\u0026lt;UP,BROADCAST,RUNNING,MULTICAST\u0026gt; mtu 1500 inet 192.168.31.158 netmask 255.255.255.0 broadcast 192.168.31.255 inet6 fe80::5054:ff:fe96:f6a1 prefixlen 64 scopeid 0x20\u0026lt;link\u0026gt; ether 52:54:00:96:f6:a1 txqueuelen 1000 (Ethernet) RX packets 1253 bytes 279527 (272.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 119 bytes 17932 (17.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 外部ネットワーク接続のテスト：\n1 2 3 4 5 [root@VM1 ~]# ping www.baidu.com PING www.a.shifen.com (183.2.172.17) 56(84) bytes of data. 64 bytes from 183.2.172.17 (183.2.172.17): icmp_seq=1 ttl=52 time=23.6 ms 64 bytes from 183.2.172.17 (183.2.172.17): icmp_seq=2 ttl=52 time=24.3 ms 64 bytes from 183.2.172.17 (183.2.172.17): icmp_seq=3 ttl=52 time=23.5 ms VI. コマンドラインによるKVM仮想マシンのインストール kickstart自動インストールスクリプトを活用することで、無人での仮想マシンの一括インストールが可能です。\n1. ディスクの作成 1 [root@cloud images]# qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/server3.qcow2 10g 2. 自動インストール virt-installでインストールソースとkickstartファイルを指定：\n1 2 3 4 5 [root@cloud ~]# virt-install -n server3 --memory 2048 --vcpu 2 \\ --disk /var/lib/libvirt/images/server3.qcow2 \\ --network bridge=br1 \\ -l http://192.168.31.96/pub \\ -x inst.ks=http://192.168.31.96/ks/ks01.cfg --vnc kickstart構成ファイルks01.cfgの例：\n1 # vim /var/www/html/ks/ks01.cfg 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #version=RHEL8 # Use text install for fully unattended text repo --name=\u0026#34;AppStream\u0026#34; --baseurl=http://192.168.0.107/pub/AppStream repo --name=\u0026#34;BaseOS\u0026#34; --baseurl=http://192.168.0.107/pub/BaseOS reboot %packages @^minimal-environment kexec-tools %end # Keyboard layouts keyboard --xlayouts=\u0026#39;us\u0026#39; # System language lang en_US.UTF-8 # Network information network --bootproto=dhcp --activate --hostname=server3 --onboot=yes # Use network installation media url --url=http://192.168.0.107/pub/BaseOS # Run the Setup Agent on first boot firstboot --disable ignoredisk --only-use=vda clearpart --all --initlabel autopart # System timezone timezone Asia/Shanghai --utc # Root password rootpw --iscrypted $6$c31XqEglO8ECIli0$enF8T.LW3OknT.178Vb9m2HHYD6dqRdKF2QZia5.G5Tv/zMD//04S2h61oBOKihJZwPIUmWxLc7oXuWtkHQy10 user --name=admin --password=$6$Ey847S5bcqYg8ktk$sd4BJeFF01IFsGOaFwRoqXoYuZ5H1RV3bLC6n6gQGa1tNAjplFDhTnm3Cjw2pgwltIE.xr27X7E/ro4gF2JSG1 --iscrypted --gecos=\u0026#34;admin\u0026#34; %addon com_redhat_kdump --enable --reserve-mb=\u0026#39;auto\u0026#39; %end %anaconda pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty %end 注意：上記のインストールソースアドレス（192.168.0.107）、ホスト名（server3）、およびrootpw、userの後のパスワードハッシュは例です。実際の使用時はご自身の環境のアドレスと生成したパスワード暗号文に置き換えてください。\n","permalink":"https://LMDAWN1127.github.io/ja/posts/kvm-virtualization-guide/","summary":"KVM仮想化技術を体系的に紹介します。発展の歴史、デプロイ方法、仮想マシン管理、ネットワークモードの構成、コマンドラインによる仮想マシンの自動インストールをカバーします。","title":"KVM仮想化 入門から実戦まで：デプロイ、管理とネットワーク構成"},{"content":"1. 適切なベースイメージを選択する 1 2 3 4 5 6 7 8 9 10 # ❌ 太大 FROM ubuntu:22.04 # ~77MB FROM python:3.11 # ~1GB # ✅ 推荐 FROM python:3.11-alpine # ~50MB FROM python:3.11-slim # ~130MB # ✅ 最小 FROM gcr.io/distroless/python3 # ~20MB ベースイメージ サイズ ubuntu:22.04 ~77MB python:3.11 ~1GB python:3.11-alpine ~50MB distroless ~20MB 2. マルチステージビルドを使用する 最も効果的な最適化手法：コンパイルステージでは大きなイメージを使い、実行ステージでは成果物だけをコピーします。\n1 2 3 4 5 6 7 8 9 10 11 # 阶段 1：编译 FROM golang:1.21 AS builder WORKDIR /app COPY . . RUN go build -o myapp # 阶段 2：运行 FROM alpine:3.18 WORKDIR /app COPY --from=builder /app/myapp . CMD [\u0026#34;./myapp\u0026#34;] Go アプリケーションが ~1GB から ~15MB に縮小されます。\n3. RUN 命令を統合する 1 2 3 4 5 6 7 8 9 10 11 12 # ❌ 多个层 RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y wget RUN rm -rf /var/lib/apt/lists/* # ✅ 合并为一个层 RUN apt-get update \u0026amp;\u0026amp; \\ apt-get install -y --no-install-recommends \\ curl \\ wget \u0026amp;\u0026amp; \\ rm -rf /var/lib/apt/lists/* 4. ビルドキャッシュのクリーンアップ 1 2 3 4 5 6 7 8 9 # Python - 禁用 pip 缓存 RUN pip install --no-cache-dir -r requirements.txt # Node.js - 清理 npm 缓存 RUN npm ci --only=production \u0026amp;\u0026amp; \\ npm cache clean --force # Go - 去除调试信息 RUN go build -ldflags=\u0026#34;-s -w\u0026#34; -o myapp 5. .dockerignore を使用する 1 2 3 4 5 6 7 8 9 10 11 # .dockerignore .git node_modules *.md .env .vscode __pycache__ *.pyc dist build coverage 1 2 # 检查上下文大小 docker build --no-cache -t test . 2\u0026gt;\u0026amp;1 | grep \u0026#34;Sending build context\u0026#34; 6. 必要なパッケージのみインストールする 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # ❌ 运行镜像里装了编译工具 FROM ubuntu:22.04 RUN apt-get install -y build-essential gcc make cmake COPY . . RUN make \u0026amp;\u0026amp; make install CMD [\u0026#34;./myapp\u0026#34;] # ✅ 编译和运行分离 FROM ubuntu:22.04 AS builder RUN apt-get install -y build-essential gcc make COPY . . RUN make \u0026amp;\u0026amp; make install FROM ubuntu:22.04 COPY --from=builder /app/myapp . CMD [\u0026#34;./myapp\u0026#34;] 7. \u0026ndash;no-install-recommends を使用する 1 2 3 4 5 # ❌ 安装了所有推荐包 RUN apt-get install -y curl # ✅ 只装必须的包（减少约 50% 依赖） RUN apt-get install -y --no-install-recommends curl 8. 静的リソースの圧縮 1 2 3 4 5 6 7 8 9 10 11 # 压缩 JavaScript RUN uglifyjs app.js -o app.min.js # 压缩 CSS RUN cssnano app.css app.min.css # 压缩图片 RUN find . -name \u0026#34;*.png\u0026#34; -exec optipng {} \\; # Go 二进制去除调试信息 RUN go build -ldflags=\u0026#34;-s -w\u0026#34; -o myapp 9. Squash でレイヤーを統合する 1 2 # 合并所有层为一层，去除中间层的重复文件 docker build --squash -t myapp:slim . /etc/docker/daemon.json で experimental 機能を有効にする必要があります。\n10. イメージレイヤーを分析する 1 2 3 4 5 6 7 # 使用 dive 工具分析每层大小和内容 docker run --rm -it \\ -v /var/run/docker.sock:/var/run/docker.sock \\ wagoodman/dive myapp:latest # 或使用 docker history docker history myapp:latest 実践例：Python アプリケーション 1 2 3 4 5 6 # ❌ 优化前（1.2GB） FROM python:3.11 WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 1 2 3 4 5 6 7 8 9 10 11 12 # ✅ 优化后（150MB，缩小 87%） FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --user -r requirements.txt FROM python:3.11-slim WORKDIR /app COPY --from=builder /root/.local /root/.local COPY . . ENV PATH=/root/.local/bin:$PATH CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 実践例：Node.js アプリケーション 1 2 3 4 5 6 # ❌ 优化前（1.1GB） FROM node:18 WORKDIR /app COPY . . RUN npm install CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 1 2 3 4 5 6 7 8 9 10 11 12 # ✅ 优化后（180MB，缩小 84%） FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM node:18-alpine WORKDIR /app COPY --from=builder /app/node_modules ./node_modules COPY . . USER node CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 推奨ツール ツール 用途 dive イメージの各レイヤーの内容とサイズを分析 docker-slim イメージを自動的にスリム化 hadolint Dockerfile の静的チェック trivy イメージのセキュリティスキャン ","permalink":"https://LMDAWN1127.github.io/ja/posts/dockerfile-smaller-image/","summary":"Docker イメージが大きすぎてデプロイが遅く、ストレージコストが高くなっていませんか？本記事では 10 の実証済み最適化テクニックを共有し、イメージを 90% 以上スリム化する方法を紹介します。","title":"Dockerfile のビルドイメージが大きすぎる？10 のテクニックでイメージを 90% スリム化"},{"content":"1. 命令の順序を適切に配置する（キャッシュの活用） 変更頻度の低い命令を前に、変更頻度の高い命令を後に配置します。あるレイヤーのキャッシュが無効になると、以降のすべてのレイヤーが再ビルドされます。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 # ❌ 错误：每次改代码都要重新装依赖 FROM node:18-alpine WORKDIR /app COPY . . # 代码经常变 RUN npm ci --production # 依赖很少变 CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] # ✅ 正确：依赖变化时才重新安装 FROM node:18-alpine WORKDIR /app COPY package.json package-lock.json ./ # 依赖定义（很少变） RUN npm ci --production # 安装依赖（很少变） COPY . . # 代码（经常变） CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 1 2 # 检查缓存命中情况 docker build -t myapp . 2\u0026gt;\u0026amp;1 | grep -E \u0026#34;(CACHED|Using cache)\u0026#34; 2. .dockerignore でコンテキストを削減する docker build は .git や node_modules など不要なファイルを含むディレクトリ全体を Docker daemon に送信します。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # .dockerignore .git .github .vscode .idea node_modules dist build *.md *.log .env .env.local .DS_Store coverage .nyc_output 1 2 3 4 # 检查上下文大小 docker build --no-cache -t test . 2\u0026gt;\u0026amp;1 | grep \u0026#34;Sending build context\u0026#34; # 优化前：Sending build context to Docker daemon 1.2GB # 优化后：Sending build context to Docker daemon 50MB 3. 軽量なベースイメージを使用する ベースイメージ サイズ 説明 ubuntu:22.04 ~77MB 完全な Ubuntu python:3.11 ~1GB 完全な Python を含む python:3.11-slim ~130MB スリム版 python:3.11-alpine ~50MB Alpine 版 1 2 3 4 5 6 7 8 # ❌ 太大 FROM python:3.11 # 1GB # ✅ 推荐 FROM python:3.11-slim # 130MB # ✅ 最小（注意 musl 兼容性问题） FROM python:3.11-alpine # 50MB Alpine は glibc ではなく musl を使用するため、一部のソフトウェアで互換性の問題が生じる可能性があります。問題に遭遇した場合は slim 版を選択してください。\n4. RUN 命令を統合してレイヤー数を削減する 各 RUN は新しいレイヤーを作成し、レイヤーが多いほどビルドが遅くなり、イメージも大きくなります。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 # ❌ 5 个层 RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y wget RUN apt-get clean RUN rm -rf /var/lib/apt/lists/* # ✅ 1 个层 RUN apt-get update \u0026amp;\u0026amp; \\ apt-get install -y --no-install-recommends \\ curl \\ wget \u0026amp;\u0026amp; \\ apt-get clean \u0026amp;\u0026amp; \\ rm -rf /var/lib/apt/lists/* 1 2 # 检查镜像层数 docker history myapp:latest 5. マルチステージビルドを使用する あるステージでビルドを行い、別のステージで実行し、必要なファイルだけをコピーします。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 阶段 1：构建 FROM golang:1.21-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o app . # 阶段 2：运行（只有 ~15MB） FROM alpine:3.18 RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /app/app . EXPOSE 8080 CMD [\u0026#34;./app\u0026#34;] 方式 イメージサイズ ビルド時間 シングルステージ ~1.2GB 5 分 マルチステージ ~15MB 2 分 6. BuildKit でビルドを高速化する BuildKit は並列ビルドと高度なキャッシュをサポートしています。\n1 2 3 4 5 6 7 # 启用 BuildKit export DOCKER_BUILDKIT=1 # 或在 /etc/docker/daemon.json 中永久配置 # { # \u0026#34;features\u0026#34;: { \u0026#34;buildkit\u0026#34;: true } # } 1 2 3 4 5 6 7 8 9 10 # 使用缓存挂载（BuildKit 特性） # syntax=docker/dockerfile:1 FROM node:18-alpine WORKDIR /app COPY package.json package-lock.json ./ # 缓存挂载避免每次重新下载依赖 RUN --mount=type=cache,target=/root/.npm \\ npm ci --production COPY . . CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] 1 2 # 检查 BuildKit 是否启用 docker build --progress=plain -t myapp . 2\u0026gt;\u0026amp;1 | head -5 7. キャッシュのインポート・エクスポートを使用する CI/CD では、キャッシュは毎回のビルド後に失われます。キャッシュのインポート・エクスポートを使うことで、ビルド間でキャッシュを保持できます。\n1 2 3 4 5 6 7 8 9 10 11 # 导出到本地 docker build \\ --cache-from type=local,src=/tmp/cache \\ --cache-to type=local,dest=/tmp/cache \\ -t myapp . # 使用注册表作为缓存 docker build \\ --cache-from type=registry,ref=myregistry/myapp:cache \\ --cache-to type=registry,ref=myregistry/myapp:cache,mode=max \\ -t myapp . 1 2 3 4 5 6 7 8 9 # GitHub Actions 示例 - name: Build and push uses: docker/build-push-action@v5 with: context: . push: true tags: myapp:latest cache-from: type=gha cache-to: type=gha,mode=max 8. 依存関係の並列インストール 1 2 3 4 5 6 7 8 9 10 11 12 # Node.js - npm ci 比 npm install 快 RUN npm ci --production # Python - 禁用缓存 RUN pip install --no-cache-dir -r requirements.txt # Go - 并行下载模块 RUN go mod download # Rust - 使用 cargo-chef COPY --from=chef /app/recipe.json recipe.json RUN cargo chef cook --release --recipe-path recipe.json 9. ビルドキャッシュと一時ファイルのクリーンアップ 同じ RUN 命令内でクリーンアップを行い、ファイルがレイヤーに残らないようにします。\n1 2 3 4 5 6 7 8 9 10 11 12 # ✅ 正确：同一层中清理 RUN apt-get update \u0026amp;\u0026amp; \\ apt-get install -y --no-install-recommends build-essential \u0026amp;\u0026amp; \\ make \u0026amp;\u0026amp; make install \u0026amp;\u0026amp; \\ apt-get purge -y --auto-remove build-essential \u0026amp;\u0026amp; \\ apt-get clean \u0026amp;\u0026amp; \\ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # ❌ 错误：清理在另一层，文件仍然存在 RUN apt-get update \u0026amp;\u0026amp; apt-get install -y build-essential RUN make \u0026amp;\u0026amp; make install RUN apt-get clean # 太晚了！前面的层已经包含了文件 各言語のクリーンアップコマンド：\n1 2 3 4 5 6 7 8 # Node.js RUN npm ci --production \u0026amp;\u0026amp; npm cache clean --force # Python RUN pip install --no-cache-dir -r requirements.txt # Go RUN go build -o app . \u0026amp;\u0026amp; go clean -cache 10. 特定バージョンのタグを使用する 1 2 3 4 5 6 7 8 # ❌ latest 可能变化，缓存不可预测 FROM node:latest # ✅ 特定版本 FROM node:18.17.0-alpine3.18 # ✅ 更安全：使用 SHA256 摘要 FROM node:18.17.0-alpine3.18@sha256:abc123... イメージレイヤーの詳細 1 2 # 查看镜像层历史 docker history \u0026lt;image-name\u0026gt; 新しいレイヤーを作成する命令：FROM、RUN、COPY、ADD\n新しいレイヤーを作成しない命令（メタデータのみ）：CMD、ENTRYPOINT、ENV、EXPOSE、WORKDIR、USER、LABEL、ARG、VOLUME\n1 2 3 4 5 6 7 8 9 10 11 # 这会创建 4 个层 FROM node:18-alpine # 层 1 RUN apk add --no-cache curl # 层 2 COPY package.json . # 层 3 RUN npm install # 层 4 # 这些指令不增加层 WORKDIR /app # 无层 ENV NODE_ENV=production # 无层 EXPOSE 3000 # 无层 CMD [\u0026#34;node\u0026#34;, \u0026#34;server.js\u0026#34;] # 无层 最適化効果の比較 1 2 3 4 5 6 7 8 9 # ❌ 优化前（8 分钟，1.2GB） FROM ubuntu:22.04 RUN apt-get update RUN apt-get install -y python3 python3-pip RUN apt-get install -y build-essential WORKDIR /app COPY . . RUN pip3 install -r requirements.txt CMD [\u0026#34;python3\u0026#34;, \u0026#34;app.py\u0026#34;] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # ✅ 优化后（1.5 分钟，150MB） # syntax=docker/dockerfile:1 FROM python:3.11-slim AS builder WORKDIR /app COPY requirements.txt . RUN --mount=type=cache,target=/root/.cache/pip \\ pip install --no-cache-dir -r requirements.txt FROM python:3.11-slim WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY . . EXPOSE 8000 CMD [\u0026#34;python\u0026#34;, \u0026#34;app.py\u0026#34;] 指標 最適化前 最適化後 改善 ビルド時間 8 分 1.5 分 81% ⬇️ イメージサイズ 1.2GB 150MB 87% ⬇️ コンテキストサイズ 500MB 50MB 90% ⬇️ キャッシュヒット率 10% 90% 80% ⬆️ 監視とデバッグ 1 2 3 4 5 6 7 8 9 10 11 # 显示详细构建时间 time docker build -t myapp . # BuildKit 详细进度 DOCKER_BUILDKIT=1 docker build --progress=plain -t myapp . # 分析镜像层 docker history myapp:latest # 使用 dive 工具深入分析 dive myapp:latest ","permalink":"https://LMDAWN1127.github.io/ja/posts/dockerfile-faster-build/","summary":"Docker のビルドが遅い？本記事では 10 の実証済み最適化テクニックを共有し、キャッシュ戦略からマルチステージビルドまで、ビルド時間を大幅に短縮する方法を紹介します。","title":"Dockerfile のビルドをより速くするには？10 の実用的な最適化テクニック"},{"content":"1. 基本構文 両者の構文はほぼ同じですが、動作には大きな違いがあります：\n1 2 3 4 5 # COPY - 纯粹的文件复制，不做任何额外处理 COPY [--chown=\u0026lt;user\u0026gt;:\u0026lt;group\u0026gt;] \u0026lt;src\u0026gt;... \u0026lt;dest\u0026gt; # ADD - 支持自动解压和远程 URL，但行为不可预测 ADD [--chown=\u0026lt;user\u0026gt;:\u0026lt;group\u0026gt;] \u0026lt;src\u0026gt;... \u0026lt;dest\u0026gt; 2. 圧縮ファイルの自動解凍 ADD はローカルの圧縮ファイルを自動的に解凍しますが、COPY は解凍しません：\n1 2 3 4 5 6 7 # ADD 自动解压 .tar.gz ADD app.tar.gz /opt/app/ # 结果：/opt/app/ 下是解压后的内容 # COPY 只复制文件本身 COPY app.tar.gz /opt/app/ # 结果：/opt/app/app.tar.gz 是原始压缩包 対応する圧縮形式：.tar、.tar.gz/.tgz、.tar.bz2、.tar.xz\n圧縮ファイル自体を解凍せずにコピーしたい場合は、COPY を使う必要があります。\n3. リモート URL のダウンロード ADD は URL から直接ファイルをダウンロードできますが、COPY はサポートしていません：\n1 2 3 4 5 # ADD 可以下载远程文件（但不推荐） ADD https://example.com/app.tar.gz /opt/ # COPY 不支持 URL COPY https://example.com/app.tar.gz /opt/ # 报错！ リモートファイルのダウンロードには RUN + curl で ADD を代替することを推奨します。ADD によるダウンロードはビルドキャッシュを利用できず、エラーハンドリングもなく、整合性の検証もできないためです。\n1 2 3 4 # 推荐：RUN + curl RUN curl -fsSL -o /tmp/app.tar.gz https://example.com/app.tar.gz \\ \u0026amp;\u0026amp; tar -xzf /tmp/app.tar.gz -C /opt/ \\ \u0026amp;\u0026amp; rm /tmp/app.tar.gz 4. ディレクトリの自動作成 どちらも存在しない中間ディレクトリを自動的に作成します：\n1 2 3 4 5 6 # 如果 /etc/myapp/config/ 不存在，会自动创建 COPY app.conf /etc/myapp/config/ ADD app.conf /etc/myapp/config/ # 不需要手动 mkdir # RUN mkdir -p /etc/myapp/config ← 多余 5. ビルドキャッシュの動作 1 2 3 4 5 # COPY - 严格匹配文件内容，内容变了才缓存失效 COPY config/app.conf /etc/app/ # ADD - 压缩文件内容相同时缓存仍然有效 ADD app.tar.gz /opt/app/ シナリオ COPY ADD ファイル内容の変化 キャッシュ無効 キャッシュ無効 ファイルメタデータの変化 キャッシュ無効 キャッシュ無効 圧縮ファイルの内容が同じ N/A キャッシュ有効 6. 機能比較 特性 COPY ADD ローカルファイルのコピー ✅ ✅ ディレクトリのコピー ✅ ✅ ワイルドカードのサポート ✅ ✅ ディレクトリの自動作成 ✅ ✅ 圧縮ファイルの自動解凍 ❌ ✅ リモート URL のサポート ❌ ✅ 意味の明確さ ✅ 高 ❌ 低 推奨使用 ✅ 第一選択 ⚠️ 特定シナリオ 7. 使用シナリオ COPY が適しているケース：\n1 2 3 4 5 6 7 8 9 # 复制配置文件 COPY nginx.conf /etc/nginx/nginx.conf # 复制应用代码 COPY src/ /app/src/ COPY package.json /app/ # 多阶段构建中复制二进制 COPY --from=builder /app/build/app /usr/local/bin/ ADD は自動解凍が必要なシナリオのみに適しています：\n1 2 3 4 5 # 合理使用 ADD ADD node-v18.17.0-linux-x64.tar.gz /usr/local/ # 普通文件不要用 ADD ADD app.conf /etc/app/ # ← 用 COPY 代替 8. ベストプラクティス 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # 规则 1：默认用 COPY COPY requirements.txt /app/ # ✅ ADD requirements.txt /app/ # ❌ 没必要 # 规则 2：只在需要解压时用 ADD ADD node-v18.tar.gz /usr/local/ # ✅ 需要解压 # 规则 3：远程文件用 RUN + curl RUN curl -fsSL -o /tmp/app.tar.gz https://example.com/app.tar.gz \\ \u0026amp;\u0026amp; tar -xzf /tmp/app.tar.gz -C /opt/ \\ \u0026amp;\u0026amp; rm /tmp/app.tar.gz # ✅ ADD https://example.com/app.tar.gz /opt/ # ❌ # 规则 4：用 .dockerignore 减少上下文 # .dockerignore # .git # node_modules # *.md # .env # 规则 5：合理安排 COPY 顺序利用缓存 COPY package.json package-lock.json ./ # 先复制依赖（变化少） RUN npm ci --production COPY . . # 再复制代码（变化多） 9. よくある落とし穴 1 2 3 4 5 6 7 8 9 10 # 陷阱 1：意外的自动解压 ADD app.tar.gz /opt/app/ # 你以为复制了文件，实际解压成了目录 # 陷阱 2：远程文件无法缓存 ADD https://github.com/user/repo/releases/download/v1.0/app.tar.gz /tmp/ # 每次构建都重新下载 # 陷阱 3：权限问题 COPY --chown=app:app src/ /app/src/ # 指定所有者 10. 選択の判断基準 1 2 3 4 5 6 7 需要复制文件？ ├── 本地压缩文件且需要解压？ │ └── 用 ADD ├── 本地普通文件？ │ └── 用 COPY └── 远程文件？ └── 用 RUN + curl ","permalink":"https://LMDAWN1127.github.io/ja/posts/dockerfile-copy-vs-add/","summary":"COPY と ADD はどちらもファイルをコピーできますが、本質的な違いがあります。本記事では両者の違いを詳しく解説し、より良い Dockerfile を書くための助けとします。","title":"Dockerfile における COPY と ADD の違いを詳しく解説"},{"content":"1. 環境要件 OS: CentOS 7/8/Stream 9 Node.js: v18 以上 メモリ: 2GB 以上を推奨 ネットワーク: Anthropic API へのアクセスが必要 2. Node.js のインストール 1 2 3 4 5 6 7 8 9 # 安装 NodeSource 仓库 curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash - # 安装 Node.js sudo yum install -y nodejs # 检查 node -v npm -v Node.js のバージョンが低い場合は、nvm でバージョンを管理します：\n1 2 3 4 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash source ~/.bashrc nvm install 20 nvm use 20 3. Claude Code のインストール 1 2 3 4 5 # 全局安装 npm install -g @anthropic-ai/claude-code # 检查 claude --version 権限の問題が発生した場合、2 つの解決策があります：\n1 2 3 4 5 6 7 8 # 方案一：sudo sudo npm install -g @anthropic-ai/claude-code # 方案二：修改 npm 全局目录（推荐） mkdir -p ~/.npm-global npm config set prefix \u0026#34;~/.npm-global\u0026#34; echo \u0026#39;export PATH=~/.npm-global/bin:$PATH\u0026#39; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc 4. API Key の設定 1 2 3 4 5 6 # 方式一：环境变量（推荐） echo \u0026#39;export ANTHROPIC_API_KEY=\u0026#34;your-api-key-here\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc # 检查 echo $ANTHROPIC_API_KEY 方法 2：claude を直接実行すると、初回起動時に API Key の入力が求められます。\n5. 基本的な使い方 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 启动交互式会话 cd /path/to/your/project claude # 直接提问（非交互模式） claude -p \u0026#34;写一个 Python 脚本，统计当前目录下所有文件的数量\u0026#34; # 分析代码 cat main.py | claude -p \u0026#34;分析这段代码的潜在问题\u0026#34; # 查看/修改配置 claude config # 更新到最新版本 claude update コマンド 説明 claude インタラクティブセッションを開始 claude -p \u0026quot;質問\u0026quot; 直接質問、非インタラクティブモード claude config 設定の確認/変更 claude update 最新バージョンに更新 6. ネットワーク問題のトラブルシューティング Anthropic API への接続がタイムアウトする場合：\n1 2 3 4 5 6 # 配置代理 export https_proxy=\u0026#34;http://your-proxy:port\u0026#34; export http_proxy=\u0026#34;http://your-proxy:port\u0026#34; # 测试连通性 curl -s https://api.anthropic.com/ | head -5 7. セキュリティの推奨事項 1 2 3 4 5 6 7 8 9 # 不要硬编码 API Key，始终用环境变量 echo \u0026#39;export ANTHROPIC_API_KEY=\u0026#34;sk-ant-xxx\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.bashrc # ✅ # ANTHROPIC_API_KEY=sk-ant-xxx 写在代码里 # ❌ # 限制文件权限 chmod 600 ~/.bashrc # 检查是否泄露 grep -r \u0026#34;ANTHROPIC_API_KEY\u0026#34; --include=\u0026#34;*.py\u0026#34; --include=\u0026#34;*.js\u0026#34; . ","permalink":"https://LMDAWN1127.github.io/ja/posts/centos-deploy-claude-code/","summary":"Claude Code は Anthropic が提供する CLI ツールで、ターミナルで直接 Claude AI と対話しながらコーディング作業を行えます。本記事では CentOS へのデプロイ手順を全工程にわたり紹介します。","title":"CentOS に Claude Code をデプロイする完全ガイド"},{"content":"flannel 実践：Docker クロスホストコンテナネットワークをゼロから構築 一、ネットワーク環境の計画 etcd ホスト IP：192.168.8.88 ホスト名：docker-network Host1 IP：192.168.8.188 ホスト名：web01 Host2 IP：192.168.8.99 ホスト名：web02 二、etcd ホストの設定 ステップ 1：etcd のダウンロードと解凍 github.com から etcd-v3.6.0-linux-amd64.tar.gz パッケージをダウンロードします パッケージを etcd ホストの /root ディレクトリにコピーして解凍します： 1 [root@docker-network ~]# tar -zxvf etcd-v3.6.0-linux-amd64.tar.gz ステップ 2：etcd 実行ファイルのインストール 1 2 [root@docker-network ~]# cd etcd-v3.6.0-linux-amd64 [root@docker-network etcd-v3.6.0-linux-amd64]# cp etcd* /usr/local/bin/ ステップ 3：データディレクトリの作成 1 [root@docker-network ~]# mkdir /var/lib/etcd ステップ 4：etcd サービスの設定と起動 etcd.service ファイルを作成します： 1 [root@docker-network ~]# vim /usr/lib/systemd/system/etcd.service 1 2 3 4 5 6 [Unit] Description=etcd_service [Service] ExecStart=/usr/local/bin/etcd --name etcd1 --data-dir /var/lib/etcd --listen-client-urls http://192.168.8.88:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.8.88:2379,http://127.0.0.1:2379 [Install] WantedBy=multi-user.target システムサービス設定をリロードして etcd を起動します： 1 2 3 [root@docker-network ~]# systemctl daemon-reload [root@docker-network ~]# systemctl enable etcd.service [root@docker-network ~]# systemctl restart etcd.service etcd のリスニング状態を確認します： 1 2 3 [root@docker-network ~]# netstat -tulnp |grep :2379 tcp 0 0 192.168.8.88:2379 0.0.0.0:* LISTEN 1912/etcd tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 1912/etcd ステップ 5：etcd に flannel ネットワーク設定を追加 1 etcdctl --endpoints http://127.0.0.1:2379 put /coreos.com/network/config \u0026#39;{\u0026#34;Network\u0026#34;: \u0026#34;172.16.0.0/16\u0026#34;, \u0026#34;SubnetLen\u0026#34;: 24, \u0026#34;SubnetMin\u0026#34;: \u0026#34;172.16.1.0\u0026#34;,\u0026#34;SubnetMax\u0026#34;: \u0026#34;172.16.10.0\u0026#34;, \u0026#34;Backend\u0026#34;: {\u0026#34;Type\u0026#34;: \u0026#34;vxlan\u0026#34;}}\u0026#39; 1 etcdctl --endpoints http://192.168.8.88:2379 get /coreos.com/network/config 設定の説明：\nNetwork：Flannel アドレスプール SubnetLen：単一のホストに割り当てる docker0 のサブネットマスク長（24ビットは 255.255.255.0） SubnetMin/SubnetMax：割り当て可能なサブネット範囲（例：172.16.1.0/24 から 172.16.10.0/24） Backend：データ転送モード（vxlan はクロスホスト通信をサポート） ステップ 6：ファイアウォールの無効化 1 2 [root@docker-network ~]# systemctl disable firewalld [root@docker-network ~]# systemctl stop firewalld 三、web01 ホストの設定（Host1: 192.168.8.188） ステップ 1：flannel のダウンロードと解凍 flannel-v0.26.7-linux-amd64.tar.gz をホストにダウンロードします ファイルを解凍します： 1 [root@web01 ~]# tar -zxvf flannel-v0.26.7-linux-amd64.tar.gz ステップ 2：flannel 実行ファイルのインストール 1 [root@web01 ~]# cp -p flanneld mk-docker-opts.sh /usr/local/bin/ ステップ 3：flannel サービスの設定と起動 flanneld.service ファイルを作成します： 1 [root@web01 ~]# vim /usr/lib/systemd/system/flanneld.service 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [Unit] Description=Flanneld Documentation=https://github.com/coreos/flannel After=network.target Before=docker.service [Service] User=root ExecStartPost=/usr/local/bin/mk-docker-opts.sh ExecStart=/usr/local/bin/flanneld --etcd-endpoints=http://192.168.8.88:2379 --iface=192.168.8.188 --ip-masq=true --etcd-prefix=/coreos.com/network Restart=on-failure Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target パラメータの説明：\n--iface=192.168.8.188：本機の etcd 接続用 IP を指定 --etcd-endpoints：etcd サーバーのアドレス サービス設定をリロードして flannel を起動します：\n1 2 3 [root@web01 ~]# systemctl daemon-reload [root@web01 ~]# systemctl enable flanneld.service [root@web01 ~]# systemctl restart flanneld.service ステップ 4：flannel ネットワークインターフェースの確認 1 [root@web01 ~]# ifconfig flannel.1 インターフェースが表示されるはずです（出力例）：\n1 2 3 4 5 6 7 8 flannel.1: flags=4163\u0026lt;UP,BROADCAST,RUNNING,MULTICAST\u0026gt; mtu 1450 inet 172.16.5.0 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::f06c:96ff:fefe:b7ab prefixlen 64 scopeid 0x20\u0026lt;link\u0026gt; ether f2:6c:96:fe:b7:ab txqueuelen 0 (Ethernet) RX packets 315 bytes 26460 (25.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 314 bytes 34636 (33.8 KiB) TX errors 0 dropped 29 overruns 0 carrier 0 collisions 0 ステップ 5：docker 設定ファイルの変更 flannel が生成したサブネット環境変数を確認します： 1 [root@web01 ~]# cat /run/flannel/subnet.env 出力例：\n1 2 3 4 FLANNEL_NETWORK=172.16.0.0/16 FLANNEL_SUBNET=172.16.5.1/24 FLANNEL_MTU=1450 FLANNEL_IPMASQ=true 1 [root@web01 ~]# cat /run/docker_opts.env 出力例：\n1 2 3 4 DOCKER_OPT_BIP=\u0026#34;--bip=172.16.5.1/24\u0026#34; DOCKER_OPT_IPMASQ=\u0026#34;--ip-masq=false\u0026#34; DOCKER_OPT_MTU=\u0026#34;--mtu=1450\u0026#34; DOCKER_OPTS=\u0026#34; --bip=172.16.5.1/24 --ip-masq=false --mtu=1450\u0026#34; docker サービス設定を変更します： 1 [root@web01 ~]# vim /usr/lib/systemd/system/docker.service [Service] セクションに以下を追加します：\n1 2 3 ExecStart=/usr/bin/dockerd $DOCKER_OPTS -H fd:// --containerd=/run/containerd/containerd.sock ExecReload=/bin/kill -s HUP $MAINPID EnvironmentFile=-/run/docker_opts.env docker サービスを再起動します： 1 2 [root@web01 ~]# systemctl daemon-reload [root@web01 ~]# systemctl restart docker.service ステップ 6：docker ネットワークの確認 nginx コンテナを作成して進入します： 1 2 3 4 5 6 7 8 9 [root@web01 ~]# ifconfig docker0: flags=4163\u0026lt;UP,BROADCAST,RUNNING,MULTICAST\u0026gt; mtu 1450 inet 172.16.5.1 netmask 255.255.255.0 broadcast 172.16.5.255 inet6 fe80::42:f6ff:fe5d:5423 prefixlen 64 scopeid 0x20\u0026lt;link\u0026gt; ether 02:42:f6:5d:54:23 txqueuelen 0 (Ethernet) RX packets 10073 bytes 407167 (397.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 48185 bytes 38083646 (36.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 1 2 [root@web01 ~]# docker run -d -p 8800:80 nginx [root@web01 ~]# docker exec -it \u0026lt;コンテナID\u0026gt; /bin/bash コンテナ IP を確認します（例：172.16.5.3）： 1 2 root@コンテナID:/# ifconfig eth0: inet 172.16.5.3 netmask 255.255.255.0 四、web02 ホストの設定（Host2: 192.168.0.208） ステップの説明 設定手順は web01 と完全に同じです。以下のパラメータのみ変更してください： --iface=192.168.8.99（本機の IP） docker コンテナ IP の例：172.16.5.2（flannel が自動割り当て） 五、実験の検証 web01 のコンテナから web02 のコンテナ IP（例：172.16.9.2）に ping を実行します：\nweb02 でコンテナを作成し、コンテナ IP アドレスを確認します\n結果：コンテナ間通信が成功し、flannel ネットワークの設定が完了しました。\n付録：etcd ネットワーク設定の確認 1 2 3 [root@docker-network ~]# etcdctl --endpoints=http://127.0.0.1:2379 get /coreos.com/network/config /coreos.com/network/config {\u0026#34;Network\u0026#34;: \u0026#34;172.16.0.0/16\u0026#34;, \u0026#34;SubnetLen\u0026#34;: 24, \u0026#34;SubnetMin\u0026#34;: \u0026#34;172.16.1.0\u0026#34;,\u0026#34;SubnetMax\u0026#34;: \u0026#34;172.16.10.0\u0026#34;, \u0026#34;Backend\u0026#34;: {\u0026#34;Type\u0026#34;: \u0026#34;vxlan\u0026#34;}} 1 2 3 [root@docker-network ~]# etcdctl --endpoints=http://127.0.0.1:2379 get /coreos.com/network/subnets --prefix --keys-only /coreos.com/network/subnets/172.16.5.0-24 /coreos.com/network/subnets/172.16.9.0-24 1 2 3 [root@docker-network ~]# etcdctl --endpoints=http://127.0.0.1:2379 get /coreos.com/network/subnets/172.16.5.0-24 /coreos.com/network/subnets/172.16.5.0-24 {\u0026#34;PublicIP\u0026#34;:\u0026#34;192.168.8.188\u0026#34;,\u0026#34;PublicIPv6\u0026#34;:null,\u0026#34;BackendType\u0026#34;:\u0026#34;vxlan\u0026#34;,\u0026#34;BackendData\u0026#34;:{\u0026#34;VNI\u0026#34;:1,\u0026#34;VtepMAC\u0026#34;:\u0026#34;5a:67:18:61:6a:5d\u0026#34;}} ","permalink":"https://LMDAWN1127.github.io/ja/posts/flannel-network-lab/","summary":"\u003ch1 id=\"flannel-実践docker-クロスホストコンテナネットワークをゼロから構築\"\u003eflannel 実践：Docker クロスホストコンテナネットワークをゼロから構築\u003c/h1\u003e\n\u003ch2 id=\"一ネットワーク環境の計画\"\u003e一、ネットワーク環境の計画\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eetcd ホスト IP：192.168.8.88 ホスト名：docker-network\u003c/li\u003e\n\u003cli\u003eHost1 IP：192.168.8.188 ホスト名：web01\u003c/li\u003e\n\u003cli\u003eHost2 IP：192.168.8.99 ホスト名：web02\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"二etcd-ホストの設定\"\u003e二、etcd ホストの設定\u003c/h2\u003e\n\u003ch3 id=\"ステップ-1etcd-のダウンロードと解凍\"\u003eステップ 1：etcd のダウンロードと解凍\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003egithub.com から etcd-v3.6.0-linux-amd64.tar.gz パッケージをダウンロードします\u003c/li\u003e\n\u003cli\u003eパッケージを etcd ホストの /root ディレクトリにコピーして解凍します：\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# tar -zxvf etcd-v3.6.0-linux-amd64.tar.gz\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"ステップ-2etcd-実行ファイルのインストール\"\u003eステップ 2：etcd 実行ファイルのインストール\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# cd etcd-v3.6.0-linux-amd64\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network etcd-v3.6.0-linux-amd64\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# cp etcd* /usr/local/bin/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"ステップ-3データディレクトリの作成\"\u003eステップ 3：データディレクトリの作成\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# mkdir /var/lib/etcd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"ステップ-4etcd-サービスの設定と起動\"\u003eステップ 4：etcd サービスの設定と起動\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eetcd.service ファイルを作成します：\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# vim /usr/lib/systemd/system/etcd.service\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e3\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e4\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e5\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e6\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-ini\" data-lang=\"ini\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[Unit]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eDescription\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003eetcd_service\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[Service]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eExecStart\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e/usr/local/bin/etcd --name etcd1 --data-dir /var/lib/etcd --listen-client-urls http://192.168.8.88:2379,http://127.0.0.1:2379 --advertise-client-urls http://192.168.8.88:2379,http://127.0.0.1:2379\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003e[Install]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#a6e22e\"\u003eWantedBy\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003emulti-user.target\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003col start=\"2\"\u003e\n\u003cli\u003eシステムサービス設定をリロードして etcd を起動します：\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e3\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# systemctl daemon-reload\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# systemctl enable etcd.service\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# systemctl restart etcd.service\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003eetcd のリスニング状態を確認します：\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e2\n\u003c/span\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e3\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003eroot@docker-network ~\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\u003cspan style=\"color:#75715e\"\u003e# netstat -tulnp |grep :2379\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etcp        \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e      \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e 192.168.8.88:2379       0.0.0.0:*               LISTEN      1912/etcd\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003etcp        \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e      \u003cspan style=\"color:#ae81ff\"\u003e0\u003c/span\u003e 127.0.0.1:2379          0.0.0.0:*               LISTEN      1912/etcd\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"ステップ-5etcd-に-flannel-ネットワーク設定を追加\"\u003eステップ 5：etcd に flannel ネットワーク設定を追加\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eetcdctl --endpoints http://127.0.0.1:2379 put /coreos.com/network/config \u003cspan style=\"color:#e6db74\"\u003e\u0026#39;{\u0026#34;Network\u0026#34;: \u0026#34;172.16.0.0/16\u0026#34;, \u0026#34;SubnetLen\u0026#34;: 24, \u0026#34;SubnetMin\u0026#34;: \u0026#34;172.16.1.0\u0026#34;,\u0026#34;SubnetMax\u0026#34;: \u0026#34;172.16.10.0\u0026#34;, \u0026#34;Backend\u0026#34;: {\u0026#34;Type\u0026#34;: \u0026#34;vxlan\u0026#34;}}\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cdiv style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\n\u003ctable style=\"border-spacing:0;padding:0;margin:0;border:0;\"\u003e\u003ctr\u003e\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode\u003e\u003cspan style=\"white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd style=\"vertical-align:top;padding:0;margin:0;border:0;;width:100%\"\u003e\n\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eetcdctl --endpoints http://192.168.8.88:2379 get /coreos.com/network/config\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e設定の説明：\u003c/p\u003e","title":"flannel 実践：Docker クロスホストコンテナネットワークをゼロから構築"}]