• Docker容器获取宿主机信息


     最近在做产品授权的东西,开始宿主机为Window,程序获取机器硬件信息相对简单些,后来部署时发现各种各样的的环境问题,所有后来改用dokcer部署,docker方式获取宿主机信息时花了些时间,特此记录一下

     

     

    docker 获取宿主机的信息

         

    复制代码
        // dmidecode -t 4 | grep ID | tail -1 // CPUID
    
        // 系统
    
        // dmidecode -s system-serial-number // 查看系统序列号
    
        // dmidecode -s system-uuid // 查看系统UUID
    
        // dmidecode -s system-product-name  //查看服务器系统型号
    
        // dmidecode -s processor-manufacturer | tail -1 // 处理器厂家
    
        
         // 主板
    
         // dmidecode -s baseboard-product-name // 主板型号
    
         // dmidecode -s baseboard-serial-number // 主板序列号
    
         // dmidecode -s baseboard-manufacturer // 主板厂家
    复制代码

    实际项目当中,我获取了CPUID、系统序列号、系统UUID、系统型号、处理器厂家,之所有获取这么多信息标识机器,是考虑到有些信息在某些系统可能为空,而且CPUID也不唯一了,所以就多获取些。

     

    调查下来,docker 获取宿主机信息大体可以通过三种方式

    • 通过环境变量由外部传入容器内
    • 使用挂载宿主机目录方式

    • 在容器中使用ssh连接到主机

    一:通过环境变量由外部传入容器内

     大体思路是docker 支持通过-e来传递参数到容器内部程序,就像安装docker-mysql那样密码可以通过参数传递一样

    • 在DockeFile中增加环境变量配置节点 (此步骤主要用来设置参数默认,也可以省略,通过其它方式设置)
    • 在程序启动时应用获取程序变量并应用
    • 在docker run 时通过-e参数传递到容器中

     

    二:使用挂载宿主机目录方式

             确保宿主机能执行dmidecode命令(必须)

            将宿主机的如下两个目录挂载到容器中

           

    复制代码
      // dmidecode程序的目录,如果不挂载那么容器中识别不了dmidecode命令
    
      /usr/sbin/dmidecode或者/sbin/dmidecode
    
      // dmidecode调用时会使用到mem这个文件,如果不挂载会找不到文件
    
       /dev/mem
    复制代码

     

       在容器启动时增加 --privileged = true参数,让容器获得近似于宿主机root的权限

     

    三:在容器中使用ssh连接到主机

    思路:在docker容器内安装ssh,sshpass服务,通过ssh连接到宿主机执行命令,获 取宿主机信息(必须知道宿主机Ip和密码)

    步骤:

    • 安装服务 yum -y install openssh-server
    • 修改配置 vim /etc/ssh/sshd_config PermitRootLogin的值修改为yes保存退出
    • 启动ssh服务 systemctl start sshd.service
    • 设置开机启动 systemctl enable sshd.service
    • 安装sshpass yum -y install sshpass

    Window 获取设备信息帮助类

     

    复制代码
      1  /// 
      2     /// 注册帮助类
      3     /// 
      4     public class RegisterHelper
      5     {
      6         // 机器指纹字符串
      7         private static string m_FingerPrintString = string.Empty;
      8 
      9         /// 
     10         /// Get a string Unique Identification code of a computer
     11         /// 
     12         /// 
     13         public static string StringValue(string mac)
     14         {
     15             if (string.IsNullOrEmpty(m_FingerPrintString))
     16             {
     17                 m_FingerPrintString = "MAC >> " + mac + "\nCPU >> " + GetCpuId() + "\nBIOS >> " + GetBiosId() + "\nBASE >> " + GetBaseId()
     18                         + "\nDISK >> " + GetDiskId() + "\nVIDEO >> " + GetVideoId();
     19             }
     20             return m_FingerPrintString;
     21         }
     22 
     23         /// 
     24         /// First enabled network card ID
     25         /// 
     26         /// 
     27         public static string GetMacId()
     28         {
     29             return Identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
     30         }
     31 
     32         /// 
     33         /// Get the cpuID
     34         /// 
     35         /// 
     36         private static string GetCpuId()
     37         {
     38             //Uses first CPU identifier available in order of preference
     39             //Don't get all identifiers, as it is very time consuming
     40             string retVal = Identifier("Win32_Processor", "UniqueId");
     41             if (string.IsNullOrEmpty(retVal)) //If no UniqueID, use ProcessorID
     42             {
     43                 retVal = Identifier("Win32_Processor", "ProcessorId");
     44                 if (string.IsNullOrEmpty(retVal)) //If no ProcessorId, use Name
     45                 {
     46                     retVal = Identifier("Win32_Processor", "Name");
     47                     if (string.IsNullOrEmpty(retVal)) //If no Name, use Manufacturer
     48                     {
     49                         retVal = Identifier("Win32_Processor", "Manufacturer");
     50                     }
     51                     //Add clock speed for extra security
     52                     retVal += Identifier("Win32_Processor", "MaxClockSpeed");
     53                 }
     54             }
     55             return retVal;
     56         }
     57 
     58         /// 
     59         /// BIOS Identifier
     60         /// 
     61         /// 
     62         private static string GetBiosId()
     63         {
     64             return Identifier("Win32_BIOS", "Manufacturer") + " | " + Identifier("Win32_BIOS", "SMBIOSBIOSVersion")
     65                 + " | " + Identifier("Win32_BIOS", "IdentificationCode") + " | " + Identifier("Win32_BIOS", "SerialNumber")
     66                 + " | " + Identifier("Win32_BIOS", "ReleaseDate") + " | " + Identifier("Win32_BIOS", "Version")
     67                 + " | " + Identifier("Win32_BIOS", "Name");
     68         }
     69 
     70         /// 
     71         /// Main physical hard drive ID
     72         /// 
     73         /// 
     74         private static string GetDiskId()
     75         {
     76             return Identifier("Win32_DiskDrive", "Model") + " | " + Identifier("Win32_DiskDrive", "SerialNumber")
     77                 + " | " + Identifier("Win32_DiskDrive", "Signature") + " | " + Identifier("Win32_DiskDrive", "TotalHeads");
     78         }
     79 
     80         /// 
     81         /// Motherboard ID
     82         /// 
     83         /// 
     84         private static string GetBaseId()
     85         {
     86             return Identifier("Win32_BaseBoard", "Model") + " | " + Identifier("Win32_BaseBoard", "Manufacturer")
     87                 + " | " + Identifier("Win32_BaseBoard", "Name") + " | " + Identifier("Win32_BaseBoard", "SerialNumber")
     88                 + " | " + Identifier("Win32_BaseBoard", "SKU") + " | " + Identifier("Win32_BaseBoard", "Product");
     89         }
     90 
     91         /// 
     92         /// Primary video controller ID
     93         /// 
     94         /// 
     95         private static string GetVideoId()
     96         {
     97             return Identifier("Win32_VideoController", "Name") + " | " + Identifier("Win32_VideoController", "AdapterRAM");
     98         }
     99 
    100         /// 
    101         /// Return a hardware identifier
    102         /// 
    103         /// 
    104         /// 
    105         /// 
    106         private static string Identifier(string wmiClass, string wmiProperty)
    107         {
    108             string result = string.Empty;
    109             System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
    110             System.Management.ManagementObjectCollection moc = mc.GetInstances();
    111             foreach (System.Management.ManagementObject mo in moc)
    112             {
    113                 //Only get the first one
    114                 if (string.IsNullOrEmpty(result))
    115                 {
    116                     try
    117                     {
    118                         result = mo[wmiProperty]?.ToString();
    119                         break;
    120                     }
    121                     catch(Exception e)
    122                     {
    123                         LogSingleton.CreateInstance().Error(e, "Window获取硬件信息失败");
    124                     }
    125                 }
    126             }
    127             return result;
    128         }
    129 
    130         /// 
    131         /// Return a hardware identifier
    132         /// 
    133         /// 
    134         /// 
    135         /// 
    136         /// 
    137         private static string Identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
    138         {
    139             string result = string.Empty;
    140             System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
    141             System.Management.ManagementObjectCollection moc = mc.GetInstances();
    142             foreach (System.Management.ManagementObject mo in moc)
    143             {
    144                 if (mo[wmiMustBeTrue].ToString() == "True")
    145                 {
    146                     //Only get the first one
    147                     if (string.IsNullOrEmpty(result))
    148                     {
    149                         try
    150                         {
    151                             result = mo[wmiProperty]?.ToString();
    152                             break;
    153                         }
    154                         catch(Exception e)
    155                         {
    156                             LogSingleton.CreateInstance().Error(e,"Window获取硬件信息失败");
    157                         }
    158                     }
    159                 }
    160             }
    161             return result;
    162         }
    163     }
    复制代码

     

    Linux 获取设备信息帮助类

     

    复制代码
     1  public class LinuxHelper
     2     {
     3 
     4         // sudo dmidecode -t 4 | grep ID | tail -1               // CPUID
     5 
     6         // 系统
     7         // sudo dmidecode -s system-serial-number                // 查看系统序列号
     8         // sudo dmidecode -s system-uuid                         // 查看系统UUID
     9         // sudo dmidecode -s system-product-name                 // 查看服务器系统型号
    10         // sudo dmidecode -s processor-manufacturer | tail -1    // 处理器厂家
    11 
    12         // 主板
    13         // sudo dmidecode -s baseboard-product-name              // 主板型号
    14         // sudo dmidecode -s baseboard-serial-number             // 主板序列号
    15         // sudo dmidecode -s baseboard-manufacturer              // 主板厂家
    16 
    17         /// 
    18         /// Get a string Unique Identification code of a computer
    19         /// 
    20         /// 
    21         public static string StringValue()
    22         {
    23             string cpuID = GetCpuId();
    24             string serialNumber = GetSerialNumber();
    25             string productName = GetProductName();
    26             string processorManufacturer = GetProcessorManufacturer();
    27             if (string.IsNullOrWhiteSpace(cpuID) && string.IsNullOrWhiteSpace(serialNumber) && string.IsNullOrWhiteSpace(productName) && string.IsNullOrWhiteSpace(processorManufacturer)) 
    28             {
    29                 return string.Empty;
    30             }
    31             return "CPU >> " + cpuID + "\nSerialNumber >> " + serialNumber + "\nProductName >> " + productName + "\nProcessorManufacturer >> " + processorManufacturer;
    32         }
    33 
    34 
    35         /// 
    36         /// Get the cpuID
    37         /// 
    38         /// 
    39         private static string GetCpuId()
    40         {
    41             return ProcessShell("dmidecode -t 4 | grep ID | tail -1");
    42         }
    43 
    44         /// 
    45         /// SerialNumber
    46         /// 
    47         /// 
    48         private static string GetSerialNumber()
    49         {
    50             return ProcessShell("dmidecode -s system-serial-number");
    51         }
    52 
    53         /// 
    54         /// product-name
    55         /// 
    56         /// 
    57         private static string GetProductName()
    58         {
    59             return ProcessShell("dmidecode -s system-product-name");
    60         }
    61 
    62         /// 
    63         /// ProcessorManufacturer
    64         /// 
    65         /// 
    66         private static string GetProcessorManufacturer()
    67         {
    68             return ProcessShell("dmidecode -s processor-manufacturer | tail -1");
    69         }
    70 
    71         /// 
    72         ///  执行Shell命令
    73         /// 
    74         /// 
    75         /// 
    76         private static string ProcessShell(string shellCmd)
    77         {
    78             string result = string.Empty;
    79             try
    80             {
    81                 using Process process = new Process
    82                 {
    83                     StartInfo = new ProcessStartInfo("/bin/bash", "")
    84                 };
    85                 process.StartInfo.RedirectStandardInput = true;
    86                 process.StartInfo.RedirectStandardOutput = true;
    87                 process.StartInfo.UseShellExecute = false;
    88                 process.Start();
    89                 process.StandardInput.WriteLine(shellCmd);
    90                 process.StandardInput.Close();
    91                 result = process.StandardOutput.ReadToEnd();
    92                 process.WaitForExit();
    93             }
    94             catch (Exception e)
    95             {
    96                 LogSingleton.CreateInstance().Error(e, "Linux获取硬件信息失败");
    97             }
    98             return result;
    99         }
    复制代码

     

    补充:方案二在实际测试中,发布在Ubuntu 22.04 TSL版本中获取宿主机信息失败。大致错误为找不到相关文件。

    最终采取的方式为在容器中获取授权服务容器的ID,以此作为唯一标识(具体采用哪种方式看自己的实际应用环境)

    关键代码

    复制代码
     1      /// 
     2         /// 获取所有容器信息
     3         /// 
     4         /// 
     5         private static List GetContainerList()
     6         {
     7             string apiVersion = Environment.GetEnvironmentVariable("DockerApiVersin", EnvironmentVariableTarget.Process);
     8             apiVersion = string.IsNullOrWhiteSpace(apiVersion) ? "1.37" : apiVersion;
     9             string result = ProcessShell($"curl --unix-socket /var/run/docker.sock http://172.17.0.1/v{apiVersion}/containers/json");
    10             return JsonConvert.DeserializeObject>(result);
    11         }
    复制代码
    1  IList containers = GetContainerList();
    2             ContainerListResponse containerListResponse = containers.FirstOrDefault(c => c.Names.Any(n => n.Contains("tuguan-server-license")));
    3             return containerListResponse?.ID;
    // 目录挂载
    
    -v /var/run/docker.sock:/var/run/docker.sock 

     

     

     

    参考信息 :https://blog.csdn.net/qq_42910468/article/details/121387411

                       https://blog.csdn.net/weixin_42173451/article/details/123085460

  • 相关阅读:
    代码随想录刷题笔记10——动态规划
    Spring监听器-spring源码详解(五)
    部门来了个测试开发,听说是00后,上来一顿操作给我看呆了...
    语音识别技术paddlespeech的安装和使用
    微商这样做软文营销,效果提升70%
    2021年程序员自述:“别人是财源滚滚,我却是裁员滚滚”
    小试单一职责原则
    【零基础入门】ACL访问控制列表
    邻接表的链表实现——链式前向星
    云计算时代:SFP、SFP+、SFP28、QSFP+和QSFP28光纤模块详解
  • 原文地址:https://www.cnblogs.com/saodiseng2015/p/16741737.html