注:本期分享由江松原创

 

今天想谈谈我突然很想知道的一件事。就是Docker每次起容器都生成一个容器ID,还有一个默认的名称,看似好像没啥规律,这到底是个啥?谁知道Docker 容器ID一长串数字到底是多少个?因为好奇我专门去看过:

 

首先,在Daemon/Daemon.go里


func (daemon *Daemon) newContainer(name string, config *containertypes.Config, imgID p_w_picpath.ID) (*container.Container, error) {
    var (
        id             string
        err            error
        noExplicitName = name == ""
    )
    id, name, err = daemon.generateIDAndName(name)
    if err != nil {
        return nil, err
    }
...

然后


func (daemon *Daemon) generateIDAndName(name string) (string, string, error) {
    var (
        err error
        id  = stringid.GenerateNonCryptoID()
    )
 
    if name == "" {
        if name, err = daemon.generateNewName(id); err != nil {
            return "", "", err
        }
        return id, name, nil
    }
  if name, err = daemon.reserveName(id, name); err != nil {
        return "", "", err
    }
    return id, name, nil
}

就是调用Stringid包里的GenerateNonCryptoID

 

Stringid包里


// GenerateNonCryptoID generates unique id without using cryptographically
// secure sources of random.
// It helps you to save entropy.
func GenerateNonCryptoID() string {
    return generateID(false)
} 
 
func generateID(crypto bool) string {
    b := make([]byte, 32)
    r := random.Reader
    if crypto {
        r = rand.Reader
    }
    for {
        if _, err := io.ReadFull(r, b); err != nil {
            panic(err) // This shouldn't happen
        }
        id := hex.EncodeToString(b)
        // if we try to parse the truncated for as an int and we don't have
        // an error then the value is all numeric and causes issues when
        // used as a hostname. ref #3869
        if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil {
            continue
        }
        return id
    }  
}

  就是生成一个32个字节的伪随机数,没有用sha1等算法然后名字部分,就是用形容词而且是很好的形容词在左边,著名的科学家在右边。

 

/ GetRandomName generates a random name from the list of adjectives and surnames in this package
// formatted as "adjective_surname". For example 'focused_turing'. If retry is non-zero, a random
// integer between 0 and 10 will be added to the end of the name, e.g `focused_turing3`
func GetRandomName(retry int) string {
    rnd := random.Rand
begin:     
    name := fmt.Sprintf("%s_%s", left[rnd.Intn(len(left))], right[rnd.Intn(len(right))])
    if name == "boring_wozniak" /* Steve Wozniak is not boring */ {
        goto begin
}
 
// Docker, starting from 0.7.x, generates names from notable scientists and hackers.
    // Please, for any amazing man that you add to the list, consider adding an equally amazing woman to it, and vice versa.
    right = [...]string{
        // Muhammad ibn J?bir al-岣?rr?n墨 al-Batt?n墨 was a founding father of astronomy. https://en.wikipedia.org/wiki/Mu%E1%B8%A5ammad_ibn_J%C4%81bir_-%E1%B8%A4arr%C4%81n%C4%AB_al-Batt%C4%81n%C4%AB
        "albattani",
 
        // Frances E. Allen, became the first female IBM Fellow in 1989. In 2006, she became the first female recipient of the ACM's Turing Award. https://en.wikipedia.org/wiki/Frances_E._Allen
        "allen",

每个科学家还有一行简介文字说明,然后是wiki。

docker/pkg/namesgenerator/names-generator.go里是左边的形容词和好多科学家。

比如,上面代码里还有一段  if name == "boring_wozniak" /* Steve Wozniak is not boring */ {        goto begin    }

就是如果容器名字不幸命中了boring_wozniak, 那么另外选一个名字;因为Docker作者认为Steve Wozniak不是太boring。

看Docker源码还能顺便对科学家致敬,好的IT产品都需要人文关怀啊!本次分享到这先结束了。

————————————————————————————————————

转载于:https://blog.51cto.com/11372512/1754702