linux怎么查看本机内存大小
249
2022-10-27
Docker 学习笔记 - Dockerfile的创建和使用
Docker创建镜像一般可以分成手动创建和自动创建。手动创建是自动创建的前提,如果手动创建的镜像成功了,那么我们可以通过dockerfile来自动化这一操作。
手动创建
首先看看如何手动创建一个简单的nginx镜像
首先从一个基础镜像 centos:6.9 启动一个容器
[root@ip-172-16-1-150 ec2-user]# docker run -dit centos:6.90735b720672ffd0beb6c8c230b5cff97be8db3f458f28972828d8b8b680b3f9b[root@ip-172-16-1-150 ec2-user]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES0735b720672f centos:6.9 "/bin/bash" 3 seconds ago Up 2 seconds awesome_hodgkin
进入容器,然后进行一些操作,安装epel源,安装nginx
[root@ip-172-16-1-150 ec2-user]# docker attach 0735b720672f[root@0735b720672f /]# yum install epel-release -y[root@0735b720672f /]# yum install nginx -y
然后创建一个脚本 init.sh
#!/bin/sh service nginx start nginx -g "daemon off;"
然后退出容器,提交commit 为一个镜像
[root@ip-172-16-1-150 ec2-user]# docker commit 0735b720672f centos6.9_nginx:v5 sha256:37d894e100105a6010507ff5aad009d30398fd4e9b7ea10da56597ba57daaf9a
现在来测试一下,注意我的初始命令我强制他执行我自己写的脚本,这样可以保证他一直处于夯住的状态,而不会自动就退出容器, docker ps 命令查看他确实夯住了,没有退出
[root@ip-172-16-1-150 ec2-user]# docker run -d -p 80:80 centos6.9_nginx:v5 /bin/bash init.sh 24121b205614a3c16be4225bec7738f9e00133110e14417ec5ecb560708ab00d [root@ip-172-16-1-150 ec2-user]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 24121b205614 centos6.9_nginx:v5 "/bin/bash init.sh" 2 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp wonderful_chandrasekhar
测试是成功的。
自动创建
生产环境中,程序员会经常性地发布新的代码到代码仓库中,比如GitHub,然后我们需要把这些新的代码克隆到我们的容器环境中,提交,我们可以用dockerfile来自动化这个步骤。
dockerfile主要组成部分: 基础镜像信息 FROM centos:6.9 制作镜像操作指令 RUN yum install openssh-server -y 容器启动时执行初始命令 CMD ["/bin/bash"]dockerfile常用指令:
FROM 指定基础镜像 MAINTAINER 指定维护者信息,可以没有 LABLE 描述,标签, 和MAINTAINER的区别是可以支持多行描述 RUN 在命令前面加上RUN即可 ADD 拷贝文件到容器里面,自动解压tar文件 WORKDIR 设置当前工作目录 VOLUME 设置卷,挂载主机目录 EXPOSE 指定对外的端口(-P 随机端口) CMD 指定容器启动后的要干的事情(比如shell脚本,容易替换) dockerfile其他指令: COPY 复制文件(不会解压)rootfs.tar.gz ENV 环境变量 ENTRYPOINT 容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
下面来看看如何实现上面的步骤
例1 FROM RUN CMD
新建一个文件 dockerfile,输入下面的内容
[root@ip-172-16-1-150 nginx]# cat dockerfile FROM centos:6.9 RUN yum install -y epel-release RUN yum install -y nginx RUN service nginx start CMD ["nginx","-g","daemon off;"]
然后执行docker image build的操作,注意我的dockerfile里面的RUN操作,每一步都相当于docker run的效果,他会创建一个临时的容器,执行命令,提交成一个临时镜像;然后下一步的RUN会从上一步的临时镜像来生成新的临时容器,执行新的命令,提交成另外一个新的临时镜像,周而复始,直到结束
[root@ip-172-16-1-150 nginx]# docker image build -t centos6.9_nginx:v7 . Sending build context to Docker daemon 2.048kB Step 1/5 : FROM centos:6.9 ---> 2199b8eb8390 Step 2/5 : RUN yum install -y epel-release ---> Using cache ---> c7f51c27d606 Step 3/5 : RUN yum install -y nginx ---> Using cache ---> 6e3c1f4b2292 Step 4/5 : RUN service nginx start ---> Using cache ---> 67d67a63a321 Step 5/5 : CMD ["nginx","-g","daemon off;"] ---> Using cache ---> 868de8ae31bd Successfully built 868de8ae31bd Successfully tagged centos6.9_nginx:v7
最后测试一下, 成功!
例2 WORKDIR ADD EXPOSE
下面看另外一个例子,自动安装一个tomcat,然后从宿主机拷贝相关的文件到容器上,并且执行相关的脚本。
首先仍然是创建 dockerfile。 这次我使用了一些新的关键字。
WORKDIR 的作用类似 cd,切换目录,如果直接cd切换目录,他没有改变任何内容,因此下一次的临时容器不会有任何记录;
ADD的作用和COPY相似,都是把宿主机的内容拷贝到容器里面,前者可以自动解压tar文件,后者不行。
EXPOSE 则是开放端口。如果我们启动容器的时候使用了-P命令,他会随机映射一个端口到这个我们指定的端口
FROM centos:6.9 RUN yum install epel-release -y RUN yum install tomcat -y WORKDIR /var/lib/tomcat/webapps/ ADD xiaoniao ./xiaoniao RUN mv xiaoniao ROOT EXPOSE 8080 ADD init.sh /init.sh CMD ["/bin/bash","/init.sh"]
下面是一个简单的init.sh脚本,启动服务,确保能夯住
#!/bin/bash service tomcat start tail -f /var/log/tomcat/catalina.out
构建一个镜像试试看
[root@ip-172-16-1-150 dockerfile]# docker image build -t test:v1 --network=host . Sending build context to Docker daemon 437.8kB Step 1/9 : FROM centos:6.9 ---> 2199b8eb8390 Step 2/9 : RUN yum install epel-release -y ---> Using cache ---> d49277d3efe5 Step 3/9 : RUN yum install tomcat -y ---> Using cache ---> d25017d00000 Step 4/9 : WORKDIR /var/lib/tomcat/webapps/ ---> Using cache ---> 2c1abca7319f Step 5/9 : ADD xiaoniao ./xiaoniao ---> 7dcf2bdeb9a2 Step 6/9 : RUN mv xiaoniao ROOT ---> Running in 91a5fb4229c9 Removing intermediate container 91a5fb4229c9 ---> 592d734b5c15 Step 7/9 : EXPOSE 8080 ---> Running in e19e4548212a Removing intermediate container e19e4548212a ---> 569d84aed65b Step 8/9 : ADD init.sh /init.sh ---> 5b25e8efdf50 Step 9/9 : CMD ["/bin/bash","/init.sh"] ---> Running in 57d39a1e02df Removing intermediate container 57d39a1e02df ---> f51e7c04728c Successfully built f51e7c04728c Successfully tagged test:v1
然后启动一个容器
[root@ip-172-16-1-150 dockerfile]# docker run -d -P test:v1 7cfd8aa199d922b99fb54d5db7202a1d3b5fb4492375a0d8329addd4e3af3bbe [root@ip-172-16-1-150 dockerfile]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7cfd8aa199d9 test:v1 "/bin/bash /init.sh" 4 seconds ago Up 2 seconds 0.0.0.0:32773->8080/tcp romantic_jang
通过随机端口访问看看,成功!
例3 ENV ENTRYPOINT
我们在上面的基础上再添加一些新的服务,比如说安装一个SSH的远程访问服务,然后配置一个初始的密码,用户启动docker 容器的时候可以自己进行替换
首先修改我们的dockerfile这次我添加了两个新的关键字 ENV 和 ENTRYPOINT
ENV的作用是创建一个环境变量,ENTRYPOINT 和 CMD 类似,但是当用户手动输入初始命令时,他不会像CMD一样来替换,而是作为参数传给ENTRYPOINT后面跟的命令。如果我们同时定义了CMD和 ENTRYPOINT,CMD的内容会作为ENTRYPOINT的默认参数
WORKDIR /var/lib/tomcat/webapps/ ADD xiaoniao ./xiaoniao RUN mv xiaoniao ROOT RUN yum install openssh-server -y ENV SSH_PWD='12345' EXPOSE 8080 22 ADD init.sh /init.sh ENTRYPOINT ["/bin/bash","/init.sh"]
接下来看看init.sh 的配置,这个脚本启动tomcat和sshd的服务,然后做一个判断,如果用户输入的参数不为空,那么把用户输入的值赋值给SSH_PWD这个变量,然后用这个变量的值重置root密码,最后一条命令夯住容器
#!/bin/bash service tomcat start service sshd start if [ ! -z $1 ];then SSH_PWD=$1 fi echo "$SSH_PWD" | passwd --stdin root tail -f /var/log/tomcat/catalina.out ~
构建一下镜像
[root@ip-172-16-1-150 dockerfile]# docker image build -t test:v10 . Sending build context to Docker daemon 437.8kB Step 1/11 : FROM centos:6.9 ---> 2199b8eb8390 Step 2/11 : RUN yum install epel-release -y ---> Using cache ---> d49277d3efe5 Step 3/11 : RUN yum install tomcat -y ---> Using cache ---> d25017d00000 Step 4/11 : WORKDIR /var/lib/tomcat/webapps/ ---> Using cache ---> 2c1abca7319f Step 5/11 : ADD xiaoniao ./xiaoniao ---> Using cache ---> 7dcf2bdeb9a2 Step 6/11 : RUN mv xiaoniao ROOT ---> Using cache ---> 592d734b5c15 Step 7/11 : RUN yum install openssh-server -y ---> Using cache ---> ec03f611047c Step 8/11 : ENV SSH_PWD='12345' ---> Using cache ---> 2cef62b3c9db Step 9/11 : EXPOSE 8080 22 ---> Using cache ---> 9926c828d6ad Step 10/11 : ADD init.sh /init.sh ---> Using cache ---> 234460473e7e Step 11/11 : ENTRYPOINT ["/bin/bash","/init.sh"] ---> Using cache ---> 233721fcbeca Successfully built 233721fcbeca Successfully tagged test:v10
运行三个容器试试看,第一个不指定密码,那么root的密码就是默认的;第二个通过ENTRYYPOINT 来传递一个参数来设置密码;第三通过ENV来替换掉环境变量的值
[root@ip-172-16-1-150 dockerfile]# docker run -d --name test1 -P test:v10 5c4755b91d2f55f7596b4ce8e41728c2e9cfe71cd4eda2cdb5442f3d7ae2cd2d [root@ip-172-16-1-150 dockerfile]# docker run -d --name test2 -P test:v10 abc c6386941f451008ef39d00ae5cf7b4b6839e672eadb4ee0a5aee45de2108fc81 [root@ip-172-16-1-150 dockerfile]# docker run -d --name test3 --env "SSH_PWD=222" -P test:v10 7b174a5f6798f48fce449d13258f0469bcd806ce42dee0f745cbf728dadd35ce [root@ip-172-16-1-150 dockerfile]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b174a5f6798 test:v10 "/bin/bash /init.sh" 6 seconds ago Up 5 seconds 0.0.0.0:32817->22/tcp, 0.0.0.0:32816->8080/tcp test3 c6386941f451 test:v10 "/bin/bash /init.sh …" 31 seconds ago Up 29 seconds 0.0.0.0:32815->22/tcp, 0.0.0.0:32814->8080/tcp test2 5c4755b91d2f test:v10 "/bin/bash /init.sh" 45 seconds ago Up 43 seconds 0.0.0.0:32813->22/tcp, 0.0.0.0:32812->8080/tcp test1
最后测试一下,注意不同容器的随机不同端口连接,测试是成功的,不同的端口对应的容器我需要用不同的密码才能登陆
[root@ip-172-16-1-150 dockerfile]# ssh root@172.16.1.150 -p 32817 The authenticity of host '[172.16.1.150]:32817 ([172.16.1.150]:32817)' can't be established. RSA key fingerprint is SHA256:CJxIwKDEhR33i/FPM7cZ7eulguMcbvSHI2BPyrCaG0c. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[172.16.1.150]:32817' (RSA) to the list of known hosts. root@172.16.1.150's password: [root@7b174a5f6798 ~]# exit logout Connection to 172.16.1.150 closed. [root@ip-172-16-1-150 dockerfile]# ssh root@172.16.1.150 -p 32815 The authenticity of host '[172.16.1.150]:32815 ([172.16.1.150]:32815)' can't be established. RSA key fingerprint is SHA256:4osfshKtt/5gdxJSH4h4IVPjvM7XPGhFIweMBG206mI. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[172.16.1.150]:32815' (RSA) to the list of known hosts. root@172.16.1.150's password: [root@c6386941f451 ~]# exit logout Connection to 172.16.1.150 closed. [root@ip-172-16-1-150 dockerfile]# ssh root@172.16.1.150 -p 32813 The authenticity of host '[172.16.1.150]:32813 ([172.16.1.150]:32813)' can't be established. RSA key fingerprint is SHA256:k9IpONHp2yLviPTAVjg6XJeYViWgT5NvQyN4zFIj3Ws. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[172.16.1.150]:32813' (RSA) to the list of known hosts. root@172.16.1.150's password: [root@5c4755b91d2f ~]# exit logout Connection to 172.16.1.150 closed. [root@ip-172-16-1-150 dockerfile]#
例4 USER
这个例子里面我可以创建一个Dockerfile,里面配置一个非Root的用户,然后默认启动都是以这个用户权限来执行的。这个是通过关键字USER来指定用户的
[ec2-user@ip-172-31-9-120 non-privileged-user]$ cat Dockerfile FROM centos RUN useradd -ms /bin/bash cloud_user USER cloud_user [ec2-user@ip-172-31-9-120 non-privileged-user]$ docker build -t centos/nonroot:v 1 "docker build" requires exactly 1 argument. See 'docker build --help'. Usage: docker build [OPTIONS] PATH | URL | - Build an image from a Dockerfile [ec2-user@ip-172-31-9-120 non-privileged-user]$ docker build -t centos/nonroot:v 1 . Sending build context to Docker daemon 2.048kB Step 1/3 : FROM centos ---> 300e315adb2f Step 2/3 : RUN useradd -ms /bin/bash cloud_user ---> Running in bdbd162888ef Removing intermediate container bdbd162888ef ---> 193bf7d54d29 Step 3/3 : USER cloud_user ---> Running in e6036ea4d3a6 Removing intermediate container e6036ea4d3a6 ---> 9842e550d6d8 Successfully built 9842e550d6d8 Successfully tagged centos/nonroot:v1 [ec2-user@ip-172-31-9-120 non-privileged-user]$ docker container run -it centos/ nonroot:v1 /bin/bash [cloud_user@3f3b3b9ae6c4 /]$ whoami cloud_user [cloud_user@3f3b3b9ae6c4 /]$
重新启动容器,然后指定-u 0 以root身份登录
[ec2-user@ip-172-31-9-120 non-privileged-user]$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3f3b3b9ae6c4 centos/nonroot:v1 "/bin/bash" 4 minutes ago Exited (0) About a minute ago great_gauss 9d08e71be857 beanxyz/python "/bin/bash" 18 hours ago Exited (0) 18 hours ago kind_curran 9983e12fbf30 beanxyz/python "/bin/bash" 18 hours ago Exited (0) 18 hours ago mystifying_solomon 53808f4bc2c5 10c5dc8f8779 "/bin/bash" 18 hours ago Exited (0) 18 hours ago kind_stonebraker 5ea958e553c4 nginx "/docker-entrypoint.…" 18 hours ago Up 18 hours 80/tcp nginx-volume2 4b09e83a6b05 nginx "/docker-entrypoint.…" 18 hours ago Up 18 hours 80/tcp nginx-volume1 07f70a9dbd1d nginx "/docker-entrypoint.…" 18 hours ago Up 18 hours 80/tcp nginx-bind-mount2 0e7c87aa0ddb nginx "/docker-entrypoint.…" 18 hours ago Up 18 hours 80/tcp nginx-bind-mount1 b647b268f977 nginx "/docker-entrypoint.…" 26 hours ago Up 26 hours private-nginx 2b99c0274c5c centos "/bin/bash" 26 hours ago Exited (127) 26 hours ago cant-ping-mysql 72639a4356e8 centos "/bin/bash" 26 hours ago Up 26 hours ping-mysql fd589dd30df0 mysql:5.7 "docker-entrypoint.s…" 26 hours ago Up 26 hours test_mysql 347a60a54b6e nginx "/docker-entrypoint.…" 26 hours ago Up 26 hours 80/tcp network-test04 6ad5891d90db linuxacademycontent/weather-app "/bin/sh -c ./bin/ 27 hours ago Up 27 hours 0.0.0.0:80->3000/tcp weather-app 1321dd64068c nginx "/docker-entrypoint.…" 27 hours ago Up 27 hours 80/tcp sleepy_lehmann 98aea78f2a02 nginx "/docker-entrypoint.…" 28 hours ago Up 28 hours 80/tcp quirky_lederberg [ec2-user@ip-172-31-9-120 non-privileged-user]$ docker container start 3f3b3b9ae6c4 3f3b3b9ae6c4 [ec2-user@ip-172-31-9-120 non-privileged-user]$ docker container exec -u 0 -it 3f3b3b9ae6c4 /bin/bash [root@3f3b3b9ae6c4 /]#
例5 VOLUME
我们在看最后一个例子,看看如何在Dockerfile里面如何使用VOLUME 来自动挂载
Dockerfile
FROM nginx:latest VOLUME ["/usr/share/nginx/html/"]
创建Image和容器
[ec2-user@ip-172-31-9-120 volumes]$ docker image build -t linuxacademy/nginx:v1 . Sending build context to Docker daemon 2.048kB Step 1/2 : FROM nginx:latest ---> 6084105296a9 Step 2/2 : VOLUME ["/usr/share/nginx/html/"] ---> Running in 2a5a749cfad9 Removing intermediate container 2a5a749cfad9 ---> 31e5c0144faf Successfully built 31e5c0144faf Successfully tagged linuxacademy/nginx:v1 [ec2-user@ip-172-31-9-120 volumes]$ docker container run -d --name nginx-volume linuxacademy/nginx:v1 d4e6605f9b1889460cbb6aca568bb65142773a495d5be7a06879bb75e7a09442
查看一下挂载信息,可以看见他自动已经创建了一个volume
[ec2-user@ip-172-31-9-120 volumes]$ docker container inspect nginx-volume | grep Mount -A10 "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, -- "Mounts": [ { "Type": "volume", "Name": "dd9f36776c98a13b74b2c0f97f6c4c01ce882f035d46598da34eaf985422637e", "Source": "/var/lib/docker/volumes/dd9f36776c98a13b74b2c0f97f6c4c01ce882f035d46598da34eaf985422637e/_data", "Destination": "/usr/share/nginx/html", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }
查看一下volume的信息,使用ls查看一下,已经有了nginx的文件了,说明挂载成功了
[ec2-user@ip-172-31-9-120 volumes]$ docker volume inspect dd9f36776c98a13b74b2c0f97f6c4c01ce882f035d46598da34eaf985422637e [ { "CreatedAt": "2021-03-28T08:21:07Z", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/dd9f36776c98a13b74b2c0f97f6c4c01ce882f035d46598da34eaf985422637e/_data", "Name": "dd9f36776c98a13b74b2c0f97f6c4c01ce882f035d46598da34eaf985422637e", "Options": null, "Scope": "local" } ] [ec2-user@ip-172-31-9-120 volumes]$ sudo ls -la /var/lib/docker/volumes/dd9f36776c98a13b74b2c0f97f6c4c01ce882f035d46598da34eaf985422637e/_data total 8 drwxr-xr-x 2 root root 40 Mar 28 08:21 . drwxr-xr-x 3 root root 19 Mar 28 08:21 .. -rw-r--r-- 1 root root 494 Mar 9 15:27 50x.html -rw-r--r-- 1 root root 612 Mar 9 15:27 index.html
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~