docker学习笔记(实时更新)。
2021年8月10日更新,前面的删除了。
一年了,工作中断断续续要部署环境,但docker用的不多,但docker确实非常好用,随着知识的增加,写一些个人的理解,便于自己记录学习。
docker的学习,网上有很多,基本就是对着命令一堆操作,原理基本也没啥人讲,为什么加i,为什么加t,有什么用,B站也有个啥狂神的讲过docker,看了一半就放弃了,野路子的课程看不得。
中间插一下,大家学习,如果视频学习,建议看好的大学的老师讲课,比较严谨,网上的,比如自媒体,培训机构等等,基本就是教流水线工作,自己也一知半解。
讲一下,我自己的理解,基础就暂时跳过了。
我主要讲一些我对run的参数,已经attach还有exec的理解,以下内容仅供参考,本人水平也有限。
当我们运行一个docker镜像,启一个容器的时候,首先最好去docker的官网去该镜像的主页查看相关启动信息的配置。
比较mysql就是:https://hub.docker.com/_/mysql
网站里面会比较详细的介绍,该镜像的启动与配置。
一般在docker启动一个容器会调用参数 -itd,-d比较好理解,就是后台启动,-it启动还是很有意思的,在exec中也会用到--it,百度上面一堆说要一起使用。
--interactive , -i |
Keep STDIN open even if not attached |
--tty , -t |
Allocate a pseudo-TTY |
当我们启动一个centos的容器时,执行docker run -d centos,这个centos并不会在后台运行,而是直接停止了,因为默认他没有任何进程在跑。
我后面尝试了docker run -d centos bash,但还是直接停止了。我的理解是,当启动这个centos内核,如果后面没有执行命令,那就启动该内核以后停止了,
当我运行docker run -d centos bash -c 'echo 123',我的终端输出了123,然后又退出了centos,也没有在后台运行。
所以加入我们需要这个centos的容器一直执行,必须需要一个能够让某一个进程启动以后,一直运行。bash就是一个独立的启动经常,如何让bash一直启动,它需要一个ttl的终端。
关于终端的解释,知乎有一个人的回答,跟我理解的差不多。
个人理解:
- 终端(Terminal)是对字符输入输出设备的抽象,在Linux中terminal是一种特殊的文件,在/dev目录下。通常情况下,键盘输入会写这个文件,而对应的终端驱动程序会执行诸如回显的工作(可以通过stty改变驱动程序的默认行为),如果没有了terminal,那么就无法响应键盘的输入。
- shell的本质是一个软件,这个软件中可以通过fork + exec + wait去加载别的可执行程序并运行。如果没有了shell,那么我们输入'ls'的时候,只会回显'ls'字符,并不会执行ls这个程序,所以shell的工作就是解析我们的输入字符,并执行对应的指令。
- Terminal和shell之间有什么关系呢?当我们去运行shell软件的时候,shell的stdin、stdout和stderr会打开并指向一个特定的terminal文件,这样导致我们通过键盘的输入实际上是写到terminal文件里面,但是shell也可以通过他的stdin从这个terminal文件中读到。
作者:maowei117
链接:https://www.zhihu.com/question/21711307/answer/865554228
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
从上面的解释来看,bash的执行需要一个终端的环境,或者一个持续的输入,这样bash才会持久的运行,经过我测试,在run的时候,通过-id或者-td的形式,直接启动centos不加任何参数,也能启动容器,并一直运行。
对与shell的理解与terminal的理解还是太少了,昨天又从网上去查询了一些相关的知道。shell就是一个解释器,,提供给用户一个可以交互与非交互式的使用,我做Python,就好比你执行了Python的命令,启动Python进程进入交互模式使用一样的道理,只不过shell是Linux官方规定的与操作系统内核进行交互的工具。
前面我转载过一篇关于交互与非交互,login与nologin的登录环境区别,前面的那个作者的解释shell的原理还是非常到位的。所以前面在默认的情况下,如果不加it的情况,那就是非交互的情况,当给予后面的一个命令时候
比如docker run centos ls我理解的差不多过程为启动centos,登录root,启动默认的bash,执行ls,最后输出到终端,当bash以非交互的方式启动完成命令之后,系统进程也将退出。
这就很好理解,当我们ssh登录一台服务器的时候,是按照交互式的方式进行登录,默认的bash一直在等待用户的输入,知道你关闭或者退出该终端,该运行的bash进程才退出,默认情况下它所启动的守护进程也将退出,除非用了nohup。有了这个理解,再去理解-it为什么能够让centos一直运行了,因为无论使用了-i或者-t都能够让该启动bash按照交互的方式一直运行,从而使整个centos容易一直运行。当无论用前面的哪种模式让容器一直运行,后续都可以从exec的方式与运行的容器进行交互。
(sidian) [sidian@localhost ~]$ docker run -i centos cd /dev/pts ls ptmx (sidian) [sidian@localhost ~]$ docker run -it centos [root@04e59de16022 /]# ls /dev/pts 0 ptmx [root@04e59de16022 /]#
上面我插入了通过-i与-it的情况下,进入bash下,查看pts下的终端硬件情况,一下子就感觉豁然开朗了。在-i的情况下,终端pts没有新的硬件[虚拟终端产生],而另外一个就不一样,当我们通过ssh登录一台服务器的时候,默认都会新建一个虚拟终端。
有了这一层的理解,我对启动这个centos的理解就是,当我们通过run启动的时候,会以非交互的方式,以root用户执行bash,当命令执行完毕以后退出,当通过-it的参数时候,会以交互式的方式登录,并执行bash,且该pid为1,当我们以run的方式启动centos,该启动的进程均为pid为1,所以你在后面加了bash或者sh的参数,可以更换不同的shell,但该shell的pid任为1.
后面的attach以及exec,待我后续知识更加丰富再来补充。
参考的attach:
深入探究docker attach的退出方式
https://www.cnblogs.com/doujianli/p/10048707.html
简单理解:就是接入正在运行的终端接口。
exec
一般进入容器使用,带上-it参数,后面必须带上命令。一般为shell的命令,比如bash,然后进入容器的shell进行交互操作
最后记录一台,我在服务器上启动MySql的命令
docker run -p 3306:3306 --name mysql -v /home/mysql/log:/var/log/mysql -v /home/mysql/data:/var/lib/mysql -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.26
docker run -p 3306:3306 --name mysql -v /home/mysql/log:/var/log/mysql -v /home/mysql/data:/var/lib/mysql -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.26