Docker部署的时候从容器获取宿主机的CPU等信息

        最近在使用go开发后台的时候,有这么一个需求,开发的服务需要做一个license,用户需要license和服务同时在且有效的情况下才能运行服务,其实在正常情况下,也没什么,但是就是因为部署的时候客户那边可能用的是docker部署,那么如何在docker里面获取到宿主机的CPU信息就成了必须,因为license需要用到宿主机的CPU信息,也可以使用主板信息或者MAC信息等,我们这次用的是CPU序列号信息,用来做license的绑定。

        我先说下我的整个流程,代码里面我先是用go语言实现了获取CPU序列号信息,使用的是linux的dmidecode命令进行的获取,命令如下

[root@dmt ~]# dmidecode -t processor | grep ID | head -1
        ID: 57 06 05 00 FF FB 8B 0F
[root@dmt ~]#

下面附上我使用go来获取CPU序列号的代码,返回两个参数,第一个是CPU序列号的字符串类型数据,第二个参数是错误码数据

//获取CPUID函数
func GET_CPUID() (string, error) {
	cmd := exec.Command("/bin/sh", "-c", `dmidecode -t processor | grep ID | head -1`)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Println("cmd.StdoutPipe: " + err.Error())
		return "", err
	}

	stderr, err := cmd.StderrPipe()
	if err != nil {
		fmt.Println("cmd.StderrPipe: ", err.Error())
		return "", err
	}

	if err := cmd.Start(); err != nil {
		fmt.Println("cmd.Start: ", err.Error())
		return "", err
	}

	bytesErr, err := ioutil.ReadAll(stderr)
	if err != nil {
		fmt.Println("ioutil.ReadAll stderr: ", err.Error())
		return "", err
	}

	if len(bytesErr) != 0 {
		fmt.Printf("stderr is not nil: %s", bytesErr)
		return "", errors.New(string(bytesErr))
	}

	bytes, err := ioutil.ReadAll(stdout)
	if err != nil {
		fmt.Println("ioutil.ReadAll stdout: ", err.Error())
		return "", err
	}

	if err := cmd.Wait(); err != nil {
		fmt.Println("cmd.Wait: ", err.Error())
		return "", err
	}
	cpuId := string(bytes)
	cpuId = strings.Replace(cpuId, "ID: ", "", -1)
	cpuId = strings.Replace(cpuId, "\t", "", -1)
	cpuId = strings.Replace(cpuId, "\n", "", -1)
	cpuId = strings.Replace(cpuId, " ", "-", -1)

	return cpuId, err
}

license的计算逻辑此处不方便公开,差不多

然后我的整个后台服务开发完成后,如果是直接在linux主机上部署,是没有任何问题的,因为直接就可以通过dmidecode命令获取到CPU的相关信息,如果是docker部署的话,需要在docker部署的yml文件里面添加如下内容。

version: '3.4'
services:
  pap:
    image: DOCKER_IMAGE
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - type: bind
        source: /usr/sbin/dmidecode
        target: /usr/sbin/dmidecode
      - type: bind
        source: /dev/mem
        target: /dev/mem
    privileged: true
    ports:
      - "8000:8000"
    restart:
          always

其中我把自己项目相关的代码都去掉了,其实最重要的就是下面这几行,每一行的作用我在后面做了备注

  • 绑定dmidecode,绑定后在docker里面也能访问dmidecode命令了
- type: bind
        source: /usr/sbin/dmidecode
        target: /usr/sbin/dmidecode
  • 绑定/dev/mem,绑定这个是因为dmidecode命令要去访问/dev/mem,不然调用dmidecode的时候会报错
- type: bind
        source: /dev/mem
        target: /dev/mem
  • 设置权限,不然到时候docker里面访问/dev/mem的时候会报权限不足,permission deny
 privileged: true

然后使用添加了这些信息的yml文件部署docker的话,程序在docker里面访问CPU信息的时候就可以正常访问了。

你可能感兴趣的:(GO语言,docker,容器,运维,docker访问宿主CPU信息)