About randomly generated container name

Introduction

When starting a container, if you do not specify --name, the container name will be randomly assigned. It is great_wescoff in the following.

$ docker run alpine:latest

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS                      PORTS     NAMES
0772fae09ab1   alpine:latest   "/bin/sh"   16 seconds ago   Exited (0) 15 seconds ago             great_wescoff

Suddenly, I was wondering how this name was generated.

How to find out

Since it is open source, you can find the answer by looking at it, but I will try to find out for myself and finally match the answers.

The way to find out is to run a lot of docker runs, extract (almost) all the names patterns, and look at them to find the rules.

$ docker run -d alpine:latest

Run some image. The image to be executed can be anything, but I chose the one that is as lightweight as possible. The -d option is a command that runs the container in the background. However, this time it is used to output the container ID, not for that purpose.

$ docker ps -a -f "id=$cid" --format "{{.Names}}"

Extract the container name using the container ID (cid) output earlier. Display all containers (including those that do not appear during execution) with the -a option, Filter by container ID with the -f option and Customize the display format with --format.

$ docker rm $cid

If the container name can be extracted, the rest is useless, so delete it.

Execute

script

Create a shell script by combining the above docker commands.

names is the file that contains the list of container names. Get 1000 container names, and if all 1000 are duplicated with the accumulated container names, it will end. Until then, it loops infinitely.


total=0
while true; do
    
    for i in `seq 1000`; do
        cid=$(docker run -d alpine:latest)
        docker ps -a -f "id=$cid" --format "{{.Names}}" >> names
        docker rm $cid > /dev/null
    done
    
    sort -u names -o names
    after_wc=$(cat names | wc -l | tr -d ' ')
    
    if [ "$total" = "$after_wc" ]; then
        exit
    else
        echo "continue (find new name: $(($after_wc-$total)))"
        total=$after_wc
    fi
    
done

One day later ...

The process wasn't finished, so I decided to speed it up a bit. At this point, the number of new names has dropped to about 500 for each epoch, so it seems that it will level off somewhere.

After all, the part that executes the docker command is the bottleneck, so I decided to execute it in parallel to some extent.

total=0

get_name() {
    for i in `seq 100`; do
        cid=$(docker run -d alpine:latest)
        docker ps -a -f "id=$cid" --format "{{.Names}}" >> names
        docker rm $cid > /dev/null
    done
}
export -f get_name

while true; do

    seq 10 | xargs -I ZZ -P 10 sh -c get_name
    
    sort -u names -o names
    after_wc=$(cat names | wc -l | tr -d ' ')
    
    if [ "$total" = "$after_wc" ]; then
        exit
    else
        echo "continue (find new name: $(($after_wc-$total)))"
        total=$after_wc
    fi
    
done

Make the part to get the name a function and execute it in 10 parallels. If the number of parallels is large, the processing can be speeded up, but due to PC specifications, the following errors frequently occur, and in the worst case docker does not work.

Error response from daemon: You cannot remove a running container 54161ca2bea3d750a3e873a329a760af990dfcc115cb13ecec322cb2f3eff85a. Stop the container before attempting removal or force remove
ERRO[0003] error waiting for container: context canceled

Occasionally it happens even in this version with 10 parallels of 100 iterations.

Two days later ...

After all, this loop didn't end, but I stopped because I could only find about 10 new names for each epoch. We will find the law here.

analysis

It's said to be an analysis, but I just look at the extracted container names and think that there seems to be a law like this.

The number of names found is `` `25422. There are likely to be hundreds more undiscovered names. The name always contains an underscore ( _```), which seems to be the character that separates the preceding and following words. Let's list this word. Also, this word does not seem to be duplicated before and after, so I will list it separately.

sed -e 's/_.*//g' names > names_first
uniq names_first names_first_uniq
admiring adoring affectionate agitated amazing angry awesome beautiful blissful bold boring brave busy charming clever compassionate competent condescending confident cool cranky crazy dazzling determined distracted dreamy eager ecstatic elastic elated elegant eloquent epic exciting fervent festive flamboyant focused friendly frosty funny gallant gifted goofy gracious great happy hardcore heuristic hopeful hungry infallible inspiring intelligent interesting jolly jovial keen kind laughing loving lucid magical modest musing mystifying naughty nervous nice nifty nostalgic objective optimistic peaceful pedantic pensive practical priceless quirky quizzical recursing relaxed reverent romantic sad serene sharp silly sleepy stoic strange stupefied suspicious sweet tender thirsty trusting unruffled upbeat vibrant vigilant vigorous wizardly wonderful xenodochial youthful zealous zen

Since the word after it must be sorted, the command used in the above extraction script is used.

sed -e 's/.*_//g' names > names_second
sort -u names_second -o names_second_uniq
agnesi albattani albattani2 allen allen7 almeida antonelli antonelli6 archimedes archimedes0 archimedes3 ardinghelli aryabhata aryabhata6 austin austin3 babbage banach banzai bardeen bartik bassi bassi0 bassi2 beaver bell benz benz9 bhabha bhaskara black black0 blackburn blackburn3 blackwell bohr booth booth6 borg bose bose2 bose6 bouman boyd boyd4 brahmagupta brahmagupta3 brahmagupta4 brattain brattain8 brown buck burnell burnell4 cannon cannon3 cannon7 carson carson8 cartwright carver cerf chandrasekhar chaplygin chatelet chatelet8 chatterjee chaum chebyshev clarke cohen colden colden4 cori cray cray5 curie curie9 curran curran2 darwin darwin8 davinci davinci3 davinci7 dewdney dewdney1 dhawan diffie dijkstra dijkstra4 dijkstra6 dirac driscoll driscoll1 dubinsky easley edison einstein elbakyan elgamal elion elion8 ellis engelbart euclid euclid4 euler euler0 faraday faraday5 feistel feistel9 fermat fermat2 fermi fermi5 feynman feynman2 franklin gagarin galileo galois ganguly gates gauss germain goldberg goldstine goldstine5 goldstine9 goldwasser goldwasser9 golick golick7 goodall gould greider greider1 grothendieck haibt hamilton haslett haslett5 hawking hawking7 heisenberg hellman hellman1 hermann herschel hertz heyrovsky heyrovsky0 hodgkin hodgkin5 hofstadter hofstadter7 hoover hoover2 hopper hugle hypatia ishizaka jackson jang jemison jennings jennings9 jepsen jepsen7 jepsen8 johnson joliot jones jones2 jones7 kalam kalam6 kapitsa kare kare8 keldysh keldysh0 keller kepler kepler8 khayyam khayyam5 khayyam9 khorana kilby kilby0 kirch knuth knuth5 kowalevski lalande lalande5 lamarr lamarr8 lamport leakey leavitt leavitt1 lederberg lehmann lewin lichterman liskov lovelace lumiere lumiere1 mahavira margulis matsumoto matsumoto9 maxwell maxwell4 maxwell8 mayer mccarthy mcclintock mclaren mclaren2 mclaren5 mclean mclean7 mcnulty mcnulty8 meitner mendel mendeleev meninsky meninsky3 merkle mestorf mirzakhani montalcini montalcini7 moore moore0 morse moser murdock murdock4 napier nash nash2 neumann newton nightingale nobel noether noether6 northcutt noyce panini pare pascal pascal3 pasteur payne perlman perlman3 pike poincare poitras poitras3 proskuriakova ptolemy ptolemy6 raman ramanujan rhodes ride ride5 ritchie robinson roentgen rosalind rubin saha sammet sammet4 sanderson satoshi shamir shannon shaw shaw4 shirley shockley shtern shtern1 sinoussi snyder solomon solomon5 solomon7 spence stonebraker sutherland swanson swanson5 swartz swartz6 swirles taussig tereshkova tesla tesla4 tharp tharp0 thompson thompson7 torvalds torvalds7 tu turing varahamihira vaughan villani visvesvaraya visvesvaraya0 visvesvaraya3 volhard volhard4 wescoff wescoff1 wilbur wilbur6 wilbur9 wiles williams williams1 williamson wilson wilson9 wing wozniak wozniak2 wright wright5 wu wu1 yalow yalow0 yonath zhukovsky

Assuming that there are no words that have not yet appeared, I guess that the container name is created by combining these 108 x 350 words.

In that case, the number of combinations will be 37800, so I regret that the script was inefficient and the number of trials was not enough.

check the answer

I followed the source code, relying on the words extracted above.

https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go

It seems that the outline was captured, but it was not what I expected. Depending on the combination of __108 x 237 words and the number of retries given as an argument, a number from 0 to 9 was randomly added to the end __. (However, except for the combination of boring and wozniak)

In response to this, out of the 350 trailing words I extracted, excluding the ones with numbers, the number is exactly 237. In other words, it seems that all the candidate words could be extracted before and after.

However, the total number of theoretical combinations, including the numbers given at random, is (108 * 237-1) * 11 = 281545 (and the probability of giving numbers is low), which is tremendous. So I stopped and it was the correct answer.

That's it. I was curious about it, but it was a meaningful survey because I learned a lot (especially about shells) while I was researching it.

Recommended Posts

About randomly generated container name
About Docker, disguise server and container