1 OpenStackについて これは、パブリック クラウドとプライベート クラウドの展開と管理を実装する IaaS オープン ソース プロジェクトです。最も人気のあるオープンソース クラウド ソリューションの 1 つになりました。その中で、コンピューティング サービス コンポーネント Nova、ネットワーク サービス コンポーネント Neutron、ブロック ストレージ サービス コンポーネント Cinder が OpenStack のコア コンポーネントです。ここでは Nova と Cinder のコンポーネントに焦点を当て、Neutron のコンポーネントについては次の記事で詳しく紹介します。
1.1 コンピューティング サービス NovaNova このコンポーネントは、AWS の EC2 サービスと同様に、OpenStack にコンピューティング サービス (Compute as Service) を提供します。 Nova が管理する主なオブジェクトはクラウド ホスト (サーバー) であり、ユーザーは Nova API を通じてクラウド ホスト (サーバー) リソースを申請できます。クラウド ホストは通常、仮想マシンに対応しますが、必ずしもそうとは限りません。コンテナ (docker ドライバー) またはベアメタル マシン (ironic ドライバーとのインターフェイス) の場合もあります。 Nova がクラウド ホストを作成するために必要な 3 つのパラメーターは次のとおりです。
クラウド ホストを作成するための CLI は次のとおりです。
nova list を使用して、テナントのすべてのクラウド ホストのリストを表示します。 1.2 ブロックストレージサービス Cinder Cinder コンポーネントは、AWS の EBS サービスと同様に、OpenStack にブロック ストレージ サービス (Block Storage as Service) を提供します。 Cinder によって管理される主なオブジェクトはデータ ボリュームです。ユーザーは、Cinder API を通じて、ボリュームの作成、削除、拡張、スナップショット、バックアップなどの操作を実行できます。 ボリュームを作成するには、次の 2 つのパラメータが必要です。
20G のボリュームを作成します。
現在、Cinder の最も一般的なアプリケーション シナリオは、Nova クラウド ホストにクラウド ハード ディスク機能を提供することです。ユーザーはボリュームを Nova クラウド ホストにマウントし、それをクラウド ホストの仮想ブロック デバイスとして使用できます。 ボリュームのマウントは Nova 側で行います。 nova ボリュームアタッチ ${server_id} ${volume_id} Cinder は、Nova クラウド ホストにクラウド ハード ディスク機能を提供するだけでなく、ベア メタル マシン、コンテナーなどにデータ ボリューム機能を提供することもできます。John Griffith は、Cinder を使用して Docker にボリューム機能を提供する方法についてブログ記事を書いています: Cinder は Nova 以外にもブロック ストレージを提供します。 次の記事では、OpenStack がボリュームを仮想マシンにマウントする方法に焦点を当て、Nova と Cinder 間の相互作用を分析します。 2 ストレージの基本 2.1 iSCSIとは iSCSI は、TCP/IP を介してブロック デバイスを共有するためのプロトコルです。このプロトコルを通じて、サーバーはローカル ブロック デバイスを他のサーバーと共有できます。つまり、このプロトコルは、インターネット経由でデバイスに SCSI コマンドを送信することを実装します。 iSCSI サーバーはターゲットと呼ばれ、クライアントはイニシエーターと呼ばれます。サーバーは複数のターゲットを同時に実行できます。ターゲットは、複数のバックストアを含めることができる物理ストレージ プールと考えることができます。 Backstore は共有するデバイスです。実際のアプリケーションには主に 2 つの種類があります。
上記 2 つのカテゴリの他に、pscsi、ramdisk なども存在します。 指定されたターゲットにバックストアを追加する必要があります。これにより、これらの物理デバイスが論理デバイスにマップされ、LUN (論理ユニット番号) と呼ばれる ID が割り当てられます。 iSCSI をより深く理解するために、次のセクションでは iSCSI の使用方法を手動で段階的に練習します。 2.2 iSCSIの実践 まず、ターゲットとしてiscsiサーバーを準備します。ここでは、CentOS 7 を例に、iscsi サービスをインストールして起動します。
targetcli を実行して、インストールが成功したかどうかを確認します。
すべてが正常であれば、targetcli シェルに入ります。すべてのバックストアと iSCSI ターゲットを表示するには、ルート ディレクトリで ls コマンドを実行します。 具体的な targetcli コマンドについては、公式ドキュメントを参照してください。ここで注目すべきは、targetcli シェルにはコンテキスト セッションがあり、これは Linux ファイル システム ディレクトリとして簡単に理解できるということです。さまざまな機能は、現在いるディレクトリの場所に対応しています。たとえば、/backstores ディレクトリにいる場合はバックストアを管理でき、/iscsi ディレクトリにいる場合はすべての iscsi ターゲットを管理できます。 pwd で現在の作業ディレクトリを表示したり、cd で作業ディレクトリを切り替えたり、help で現在の作業環境のヘルプ情報を表示したり、ls でサブディレクトリ構造を表示したりすることができます。コマンドの補完には Tab キーを使用できますが、これは Linux シェルの操作と非常によく似ているため、比較的簡単に使用できます。 簡単にするために、fileio タイプのバックストアを作成します。まず、/backstores/fileio ディレクトリに cd します。
test_fileio という名前の fileio タイプのバックストアを作成しました。ファイル パスは /tmp/test_fileio.raw、サイズは 2G で、ファイルが存在しない場合は自動的に作成されます。 バックストアを作成した後、ターゲットを作成し、/iscsi ディレクトリに cd します。
上記では、int32bit という名前のターゲットを作成しました。先頭の iqn.2017-09.me.int32bit は iSCSI 修飾名 (IQN) です。具体的な意味については、Wikipedia-ISCSI を参照してください。ここでは、単純に一意の名前空間として理解できます。 ls コマンドを使用して、ディレクトリ iqn.2017-09.me.int32bit:int32bit が作成されたことがわかりました (注: 実際にはディレクトリではありませんが、ここではこのように理解します)。 ターゲットを作成した後、ターゲットをエクスポートする、つまり、ポータルと呼ばれるリスニング状態に入る必要があります。ポータルの作成も非常に簡単です。
上記では、10.0.0.4 がサーバーの IP アドレスです。ポートが指定されていない場合は、デフォルトのポート 3260 が使用されます。 ターゲットが作成されました。これで、先ほど作成したバックストアをこのターゲットに追加できます。
この時点で、ターゲットには lun デバイスが含まれています。
次に、クライアント側の iSCSI イニシエーターを構成します。
このマシンのイニシエーター名を取得します:
クライアントはサーバー ターゲットに接続する必要があり、ACL 認証も必要です。サーバーにクライアントのアクセス権を追加し、サーバー上で実行します。
注: 上記ではアカウントとパスワードを設定していないため、クライアントは直接ログインできます。 準備はすべて整いました。クライアント側でターゲットに接続しましょう。 まず、iscsiadm コマンドを使用して、ローカルで表示可能なターゲット リストを自動的に検出します。
ターゲットを見つけたら、ログインして検証することで使用できます。
ログインしているすべてのターゲットを表示できます。
この時点で、ターゲットはローカル ブロック デバイスに自動的にマップされており、lsblk を使用して表示できます。
マップされたローカルデバイスは /dev/shm であることがわかります。その後、ローカル ハード ドライブのように使用できます。 上記では、ターゲット サーバー上のローカル ファイルを通じてブロック単位でデータを共有します。これは通常、テストにのみ使用されます。実稼働環境では、実際のブロック デバイスは通常、共有用に商用ストレージによって提供されます。 OpenStack Cinder が LVM ドライバーを使用する場合、LVM ボリュームを通じて共有されます。これを達成するのは難しくありません。ブロック バックストアに LVM に対応する LV PATH を追加するだけです。この状況については、この記事の後半で詳しく説明します。 2.3 cinder-rtstool の紹介 先ほど使用した targetcli は Datera によって開発されました。Datera はこの CLI ツールを提供するだけでなく、Python ライブラリ rtslib も提供しています。プロジェクトのアドレスはrtslibです。おそらく何らかの理由で、コミュニティは rtslib プロジェクトをフォークし、「フリー ブランチ」という名前の別のブランチ、つまり rtslib-fb プロジェクトを維持しました。現在、これら 2 つのブランチは互換性がない可能性があります。そのため、targetcli、rtslib、configshell が同じバージョン ブランチ (すべて fb またはすべて non-fb) にあることを確認してください。 OpenStack コミュニティは、rtstool に基づく CLI ツールをカプセル化しました。これが、これから紹介する cinder-rtstool ツールです。このツールの使い方は非常に簡単です。ヘルプ情報を確認してみましょう:
このツールは主にターゲット側、つまり cinder-volume が配置されているノードで実行されます。 create コマンドは、対応するポータルの作成を含め、ターゲットをすばやく作成し、デバイスをターゲットに追加するために使用されます。 add-initiator は ACL の作成に対応し、get-targets は現在のサーバーによって作成されたすべてのターゲットを一覧表示します。他のコマンドについては詳しく説明しません。基本的に、その機能は推測できると思います。 2.4 ceph rbdの紹介 Ceph は、高いスケーラビリティ、高いパフォーマンス、高い信頼性の利点を備えたオープンソースの分散ストレージ システムです。また、ブロック ストレージ サービス (rbd)、オブジェクト ストレージ サービス (rgw)、ファイル システム ストレージ サービス (cephfs) も提供します。これは現在、OpenStack の主流のバックエンド ストレージであり、OpenStack に統合された共有ストレージ サービスを提供しています。 OpenStack のバックエンド ストレージとして Ceph を使用すると、少なくとも次の利点があります。
ceph の詳細については、公式ドキュメントを参照してください。ここでは rbd について簡単に紹介します。 先ほど紹介した iSCSI にはターゲットという概念があります。ストレージ デバイスを指定されたターゲットに追加し、LUN にマップする必要があります。 rbd にはプールの概念もあります。 rbd によって作成された仮想ブロック デバイス インスタンスは、イメージと呼ばれます。すべての画像はプールに含める必要があります。ここではプールの役割については説明せず、単に名前空間として理解します。 rbd コマンドを使用して rbd イメージを作成できます。
上記では、create サブコマンドを使用して、サイズが 1G の int32bit-test-rbd という名前のイメージを作成します。ここで、-p パラメータ値 test2 はプール名です。 ls コマンドを使用してすべてのイメージのリストを表示したり、info コマンドを使用してイメージの詳細情報を表示したりできます。 iSCSI が lun デバイスを作成した後、イニシエーターはログインを通じてデバイスをローカル コンピューターにマップします。 rbd イメージは、マップ操作を通じてローカル コンピューターにマップされます。クライアントに ceph クライアント パッケージをインストールし、証明書を構成したら、rbd map を使用して証明書をローカル コンピューターにマップするだけです。
この時点で、作成されたイメージをローカル ブロック デバイスとして /dev/rbd0 にマッピングしました。これで、デバイスをローカル ディスクのように使用できるようになりました。 2.5 ブロックデバイスを仮想マシンにマウントする方法 仮想マシンにブロック デバイスを提供するには、qemu-kvm で --drive パラメータを使用して指定するだけです。 libvirt を使用する場合、CLI virsh を例にとると、attach-device サブコマンドを使用してデバイスを仮想マシンにマウントできます。このコマンドには 2 つの必要なパラメータが含まれています。1 つはドメイン、つまり仮想マシン ID であり、もう 1 つはデバイスのアドレス情報を含む XML ファイルです。
iSCSI デバイスは、まず lun デバイスをホスト マシンにマップし、次にそれをローカル デバイスとしてマウントする必要があります。簡単なデモ XML は次のとおりです。
ソースは、LUN デバイスからローカル デバイスにマップされたパスであることがわかります。 libvirt は、rbd イメージの直接マウント (ホストに rbd カーネル モジュールが含まれている必要があります) と、最初にホストにマップすることなく rbd プロトコルを介してイメージにアクセスすることをサポートすることに言及する価値があります。デモの XML ファイルは次のとおりです。
したがって、Cinder で LVM ドライバーを使用する場合は、まず LV を iSCSI ターゲットに追加し、それをコンピューティング ノードのホストにマップする必要があります。 rbd ドライバーを使用する場合は、それをコンピューティング ノードにマップする必要がなく、直接マウントできます。 上記ではストレージに関する基本的な知識を紹介しました。この知識があれば、OpenStack nova と cinder を理解するのは非常に簡単です。次に、正式なトピックに入り、OpenStack 仮想マシンにデータ ボリュームをマウントするプロセスを分析します。 3 OpenStack仮想マシンボリュームマウントソースコード分析 ここでは、LVM ドライバーを使用する Ciner、lioadm を使用する iSCSI ドライバーを例に挙げ、バックエンド構成を次のようにします。
OpenStack ソースコードの読み方の詳細については、「OpenStack ソースコードの読み方」を参照してください。ここでは詳細には触れません。ここで注目すべきは、Nova には、データ ボリュームと仮想マシン間のマッピング関係を保存するために特別に使用されるデータベース テーブルがあるということです。このテーブルは block_device_mapping と呼ばれ、そのフィールドは次のとおりです。
Cinder には、マウント ステータスを記録するための別のテーブル volume_attachment もあります。
次に、nova-api から始めて、プロセスを段階的に実行します。 S1 ノヴァアピノヴァアピ ボリュームをマウントするためのエントリ ポイントは nova/api/openstack/compute/volumes.py、コントローラーは VolumeAttachmentController、仮想マシンにボリュームをマウントするためのメソッドは create です。 このメソッドは、まずボリュームが仮想マシンにすでにマウントされているかどうかを確認します。
次に、nova/compute/api.py の attach_volume メソッドを呼び出します。このメソッドは次のことを行います。 (1) ボリュームを作成する() つまり、block_device_mapping テーブルに対応するレコードを作成します。 API ノードは、マウント後にターゲット仮想マシンのデバイス名 (/dev/vdb など) を取得できないため、コンピューティング ノードのみが仮想マシンがどのデバイスにマップされているかを認識します。したがって、bdm は API ノード上に作成されず、仮想マシンが配置されているコンピューティング ノードへの RPC 要求を通じて作成されます。リクエストメソッドは reserve_block_device_name です。これは最初に libvirt を呼び出して /dev/vdb などのデバイス名を割り当て、次に対応する bdm インスタンスを作成します。 (2) チェックアタッチとボリュームの確保() これには、check_attach と reserve_volume の 2 つのプロセスが含まれます。 Check_attach はボリュームがマウントできるかどうかを確認します。たとえば、ステータスは使用可能である必要があります。また、複数のマウントがサポートされている場合は、ステータスは使用中または使用可能である必要があります。メソッドの場所は、nova/volume/cinder.py の check_attach メソッドです。 reserve_volume は Cinder によって完了し、nova-api は cinder API を呼び出します。このメソッドは実際には何も行わず、ボリュームのステータスを接続に設定するだけです。メソッド フロー: nova-api -> cinder-api -> reserver_volume、メソッドは cinder/volume/api.py にあります:
(3) RPC計算ノードのattach_volume() この時点で、nova-api はターゲット コンピューティング ノードへの RPC 要求を開始します。 rpcapi.py の attach_volume メソッドは cast メソッドを呼び出すため、RPC は非同期呼び出しになります。この時点で、nova-api の作業は完了し、残りの作業は仮想マシンが配置されているコンピューティング ノードによって完了します。 S2 ノヴァコンピューティングノヴァコンピューティング RPC リクエストを受信した後、コールバック関数のエントリは nova/compute/manager.py の attach_volume メソッドになります。このメソッドは、以前に作成された bdm インスタンス パラメータに従って driver_block_device に変換し、クラスの attach メソッドを呼び出します。これは特定のハードウェア層に到達しました。ボリュームの種類に応じて、異なる特定のクラスがインスタンス化されます。ここでのタイプはボリュームなので、nova/virt/block_device.py にある DriverVolumeBlockDevice に対応します。 仮想マシンがボリュームをマウントするための最も重要な方法であり、実装の中核でもあるアタッチ方法を見てみましょう。この方法はいくつかの段階に分かれています。一つずつ見ていきましょう。 (1) get_volume_connector() このメソッドは、まず virt_driver.get_volume_connector(instance) を呼び出します。ここで、virt_driver は libvirt です。このメソッドは nova/virt/libvirt/driver.py にあり、実際には os-brick の get_connector_properties を呼び出します。
os-brick は Cinder プロジェクトから分離されたライブラリであり、さまざまなストレージ システムのボリュームを管理するために特に使用されます。コード リポジトリは os-brick です。 get_connector_properties メソッドは、os_brick/initiator/connector.py にあります。
このメソッドの最も重要なタスクは、コンピューティング ノードの情報 (IP、オペレーティング システムの種類など) とイニシエーター名 (セクション 2 を参照) を返すことです。 (2) volume_api.initialize_connection() ついに、シンダーが実際の仕事をする番です!このメソッドは、Cinder API の initialise_connection メソッドを呼び出し、ボリュームが配置されている cinder-volume サービス ノードに RPC 要求を送信します。 cinder-api をスキップして、直接 cinder-volume に進みます。 S3 シンダーボリューム コードの場所は cinder/volume/manager.py です。この方法も段階に分かれています。 (1) ドライバ.validate_connector() この方法はドライバーによって異なります。 LVM + iSCSI の場合は、イニシエーター フィールド、つまり nova-compute ノードのイニシエーター情報があるかどうかを確認します。コードは cinder/volume/targets/iscsi.py にあります:
上記のコードジャンプ プロセスに注意してください: drivers/lvm.py -> target/lio.py -> target/iscsi.py。つまり、lvm ドライバーはターゲットの対応するメソッドを呼び出します。ここでは lio を使用するため、lio.py を呼び出します。lio は iscsi から継承するため、iscsi.py にジャンプします。以下の分析では、これらの詳細をスキップして、次のセクションに直接進みます。 (2) ドライバ.create_export() メソッドは cinder/volume/targets/iscsi.py にあります:
このメソッドの最も重要な操作は、create_iscsi_target メソッドを呼び出すことです。このメソッドは、実際には cinder-rtstool の create メソッドを呼び出します。
つまり、create_export メソッドの主なタスクは、cinder-rtstool ツールを呼び出してターゲットを作成し、デバイスをターゲットに追加することです。 cinder-volume ノードでは、targetcli を通じてエクスポートされたすべてのターゲットを表示できます。
(3) ドライバ.initialize_connection() これが最後のステップです。このメソッドは cinder/volume/targets/lio.py にあります:
この方法の重要なタスクは、cinder-rtstool の add-initiator サブコマンドを呼び出すこと、つまり、作成したばかりのターゲット ACL にコンピューティング ノードのイニシエーターを追加することです。 targetcli の出力は次のとおりです。
したがって、シンダーの主なタスクは、ボリュームのISCSIターゲットとACLSを作成することです。シンダーボリュームの作業が終了し、Nova Computeに戻ります。 S4 Nova-Compute Nova-Computeのステップ(2)に戻り、volume_api.initialize_connection()を呼び出し、ステップ(3)を実行します。 (3)virt_driver.attach_volume() この時点で、Libvirtレイヤーに到達します。コードは nova/virt/libvirt/driver.py にあります。この方法は、次の手順に分かれています。 1。_Connect_Volume()メソッドは、nova/virt/libvirt/volume/iscsi.pyのconnect_volume()メソッドを呼び出します。この方法は、実際には、OS-BrickのConnect_Volume()メソッドを直接呼び出します。この方法は、os_brick/initiator/connector.pyのiscsiconnectorクラスのconnect_volumeメソッドにあります。このメソッドは、以前に導入されたISCSIADMコマンドのディスコボリーとログインサブコマンドを呼び出します。つまり、LUNデバイスをローカルデバイスにマッピングします。 ISCSIADMを使用して、接続されているすべてのボリューム(ログイン)を表示できます。
LSBLKを使用して、マッピングパスを表示します。
Linux /dev /disk by-pathにもあります。
2。_GET_VOLUME_CONFIG() ボリュームの情報を取得するには、実際にはXMLを生成するために必要な情報です。最も重要なことは、/dev/disk/by-path/ip-0.0.0.2:3260-iscsi-iqn.2010-10.openstack:volume-060fe764-c17b-45da-af6d-868c1f5e19df-lun-0を取得することです。返されたconfは最終的にXML形式に変換されます。このコードは、nova/virt/libvirt/volume/iscsi.pyにあります:
3。Guest.Attach_Device()が最後に最後のステップに到達します。このステップは、実際には、Virsh Attach-Deviceコマンドを呼び出して、デバイスを仮想マシンにマウントすることに似ています。このコードは、nova/virt/libvirt/guest.pyにあります:
Libvirtの作業は完成し、現時点ではボリュームが仮想マシンにマウントされています。 (4)volume_api.attach() nova/virt/block_device.pyに戻り、最後にvolume_api.attach()メソッドが呼び出されます。この時点で、Cinder-APIはRPCを介してCinder-volumeを要求し、コードはCinder/Volume/Manager.pyにあります。この方法は何もしませんが、実際にデータベースを更新し、ボリューム状態を使用して使用し、対応する添付ファイルレコードを作成しています。 この時点で、OpenStackのマウントプロセス全体が最終的に終了しました。 Novaの観点から分析しています。 Cinderの観点から分析すると、Cinderには実際にはあまり作業がありません。概要は次のとおりです。
4 OpenStack仮想マシンマウントRBD分析 LVM + LIOのボリュームマウントプロセスを以前に分析しました。 RBDがマウントされた場合の違いは何ですか?ここでは、詳細なプロセスを詳細に導入するのではなく、Cinder-Volumeのinitialize_connectionから始めます。 cinder-volumeのinitialize_connectionステップを分析しました。
Ceph RBDに対応するのは非常に簡単です。 RBDはISCSIのようなターゲットやポータルを作成する必要がないため、RBDドライバーのcreate_export()メソッドは空です。
intialize_connection()メソッドも非常にシンプルであり、プール、画像名、MONアドレス、CEPH構成情報などのRBD画像情報を直接返します。
前述のように、RBDは仮想デバイスをホストにマッピングする必要がないため、Connect_Volumeメソッドも空です。 作業の残りの部分は、実際にはget_config()メソッドを呼び出して、monアドレス、RBD画像情報、認証情報などをCEPHの情報を取得し、XML形式に変換することです。最後に、guest.attach_device()を呼び出して、ボリュームマウントを完了します。 したがって、RBDマウントプロセスはISCSIよりもはるかに簡単です。 4 結論 プロセス全体を要約するには、LVM+LIOを例に取ります。ボリュームの作成からボリュームの取り付けまでのプロセスは次のとおりです。 Cinder-Volumeノードで指定されたLVMボリュームグループ(VG)でLVMボリューム(LV)の作成に相当するボリュームを作成します。 マウントボリュームはNOVAによって開始されます。 Nova-APIは、ボリュームステータスをチェックしてから、CINDERに通知します。 CINDERは、ボリュームステータスを設定して添付します。 残りの作業のほとんどは、最初にノードのISCSI名を取得するNova-Computeによって行われます。 Nova-ComputeはCinderをリクエストし、Cinderは対応するターゲットを作成し、ACLSにNova Computeノードを追加します。 Nova-Computeノードは、ISCSIAADMコマンドを介してボリュームをローカルエリアにマッピングします。このプロセスは、接続ボリュームと呼ばれます。 NOVA-Computeノードは、マウントされたXML構成ファイルを生成します。 Nova-Computeは、Virtual MachineにマウントボリュームにlibvirtのAttach-Deviceインターフェイスを呼び出します。 マウントプロセスは、次のフローチャートとして要約されています。 上記の分析は、添付APIの古いバージョンに基づいていることに注意する必要があります。コミュニティは、OCATAバージョンから新しいボリュームアタッチAPIを導入および開発しました。プロセス全体を再設計する必要がある場合があります。詳細については、新しい添付APIの追加を参照してください。この新しいAPI設計により、マルチマウントをより適切に実装し、CinderとNovaの一貫性のない状態の問題をより適切に解決します。 【この記事は51CTOコラムニスト「Fu Guangping」によるオリジナル記事です。転載が必要な場合は51CTOまでご連絡ください] この著者の他の記事を読むにはここをクリックしてください |
<<: ファーウェイのエッジコンピューティングが物理世界と仮想世界をつなぐ仕組み
Hncloud(ワーナークラウド)は、香港と米国のデータセンターにあるクラウドサーバー(OpenSt...
マルチクラウド環境で運用する組織にとって、データ ガバナンスの複雑さと課題は非常に大きいです。データ...
首都の冬、電子商取引界の内部統合が加速している。南都日報地図:宋小偉eBayオンラインマーチャントの...
最近、製品部門のユーザーエクスペリエンスチームの学生は、アライアンス環境における広告に関する一連の研...
この疫病は人々の生産や生活の仕方を変えました。共同作業、リモートワーク、オンライン教育などのシナリオ...
Cloudcone は今年最大のイースター スーパー プロモーションをお届けします。主な目玉は、1G...
簡単に言えば、SEO は 4 つのステップに分かれています。1 つ目は基本的な基準を確立すること、2...
私はこの会社でほぼ2年間働いています。多くの成功事例があり、多くの代替クライアントと出会いました。こ...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています多くの人が...
モノのインターネット (IoT) エッジ コンピューティングとは、IoT インフラストラクチャ内のセ...
Extravm は、米国東海岸のニュージャージー州ピスカタウェイに新しい米国データセンター - VP...
周知のとおり、SEO はウェブサイトの運用と保守の手段であり、その費用対効果の高さから多くの運用と保...
過去1年間、中国のインターネット市場は大きな変化を遂げ、To Bが新たなトレンドとなりました。産業用...
金曜日にタバコを吸いながら、一つの時代が終わるような気がした、と私は言った。同僚は、心機一転する時期...
新年、新しい雰囲気。2013 年はあっという間にやって来ました。新年の初めに、Baidu はすべての...