感觉作为web负责人不会Docker是一件比较奇怪的事情,所以拿零碎的时间入门了一下Docker
我这里用的是Centos系统
Install Docker Engine on CentOS | Docker Documentation
1、需要的安装包
yum install -y yum-utils
2、阿里云镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3、安装docker ce社区版 ee企业版
yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
4、启动docker
systemctl start docker
5、测试
docker run hello-world
6、查看当前镜像
docker images
卸载
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
1、Docker有着比虚拟机更少的抽象层。
2、docker利用的是宿主机的内核,vm需要的是Guest OS
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导。虚拟机是加载Guest OS,分钟级别的,而docker是利用宿主机的操作系统吗,省略了这个复杂的过程,秒级!
docker version
docker 命令 --help
docker info
docker images 查看所有本地主机上的镜像文件
可选项
-a --all #列出所有镜像
-q --quiet #只显示镜像的id
docker search 搜索镜像
docker search mysql 搜索mysql镜像
# 可选项
-- filters=STARS=3000 #搜索出镜像stars大于3000的镜像
docker pull 下载镜像
docker pull mysql:5.7
docker rmi 删除镜像
docker rmi -f 容器id #删除指定容器
docker rmi -f 容器id 容器id 容器id #删除多个指定容器
docker rmi -f $(docker images -aq) #删除全部的容器
有了镜像才能创建容器,下载centos镜像测试学习
docker pull centos
新建容器并启动
docker run [可选参数] image
#参数说明
--name="Name" 容器名字 xxx01 xxx02,用来区分容器
-d 后台运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口 -p 8080:8080
-p ip:主机端口自:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-P 随机指定端口
[root@VM-16-10-centos /]# docker run -it centos /bin/bash
[root@0c6ab50f2a8c /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@0c6ab50f2a8c /]# exit
exit
[root@VM-16-10-centos /]# ls
bin data etc lib log media opt proc run srv tmp var
boot dev home lib64 lost+found mnt patch root sbin sys usr www
列出所有运行的容器
# docker ps 命令
#列出当前正在运行的容器
-a #列出当前正在运行的容器+历史运行过的容器
-n=x #列出最近创建的x条容器
-q #只显示容器编号
退出容器
exit #停止并退出容器
Ctrl + P + Q #容器退出但不停止
删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,若要强制删除rm -rf
docker rm -f $(docker ps -aq) #删除所有容器
docker ps -a -q|xargs docker rm #删除所有容器
启动停止容器
docker start 容器id #启动融洽
docker restart 容器id #重启容器
docker stop 容器id #停止容器
docker kill 容器id #强制停止当前容器
后台启动容器
#命令 docker run -d 镜像名
[root@VM-16-10-centos /]# docker run -d centos
#问题docker ps,发现centos没有运行——docker容器后台运行后,就必须要有一个前台进程,docker若发现没有应用则会立即停止
查看日志
#命令 docker logs -f -t --tail n 容器id
-t #时间戳
-f #跟踪日志输出
[root@VM-16-10-centos /]# docker logs -f -t --tail 10 7110c7daf02d
查看容器中进程信息
# 命令 docker top 容器id
[root@VM-16-10-centos /]# docker top 7110c7daf02d
UID PID PPID C STIME TTY TIME CMD
root 6988 6968 0 08:23 pts/0 00:00:00 /bin/bash
查看镜像的原数据
# 命令 docker inspect 容器id
进入当前正在运行的容器
# 命令
docker exec it 容器id bashshell
docker attach 容器id
# 测试
[root@VM-16-10-centos /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7110c7daf02d centos "/bin/bash" 24 hours ago Up 24 hours romantic_vaughan
[root@VM-16-10-centos /]# docker exec -it 7110c7daf02d /bin/bash
[root@7110c7daf02d /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@7110c7daf02d /]# exit
exit
[root@VM-16-10-centos /]# ls
bin data etc lib log media opt proc run srv tmp var
boot dev home lib64 lost+found mnt patch root sbin sys usr www
# docker attch 容器id
# 若有正在运行的程序则attach会进入正在运行的程序,不会启动新进程
从容器内拷贝文件到主机
# 命令 docker cp 容器id:容器路径 主机路径
[root@7110c7daf02d /]# cd home
[root@7110c7daf02d home]# touch Sentiment.java
[root@7110c7daf02d home]# ls
Sentiment.java
[root@7110c7daf02d home]# exit
exit
[root@VM-16-10-centos /]# docker cp 7110c7daf02d:/home/Sentiment.java /home
[root@VM-16-10-centos /]# cd home
[root@VM-16-10-centos home]# ls
lighthouse Sentiment.java www
[root@VM-16-10-centos ]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
Digest: sha256:b95a99feebf7797479e0c5eb5ec0bdfa5d9f504bc94da550c2f58e839ea6914f
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest
[root@VM-16-10-centos ]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 2b7d6430f78d 13 days ago 142MB
[root@VM-16-10-centos ]# docker run -d --name nginx01 -p 7777:80 nginx
f955336f4e8a760d47fa0289e16825c56fe732c58d71f116c16aaef4dafab29d
[root@VM-16-10-centos ]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f955336f4e8a nginx "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:7777->80/tcp, :::7777->80/tcp nginx01
[root@VM-16-10-centos ]# curl localhost:7777
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@VM-16-10-centos ]# docker exec -it nginx01 /bin/bash
之前出了道java题,借此用docker尝试部署一下
#安装tomcat9+jdk8
[root@VM-16-10-centos home]# docker pull tomcat:9-jdk8-temurin-focal
9-jdk8-temurin-focal: Pulling from library/tomcat
675920708c8b: Pull complete
9f80c8980f9f: Pull complete
ef18550d9ddf: Pull complete
f9ef9c318985: Pull complete
058be3f9fa17: Pull complete
818a3c41a8e1: Pull complete
c85727d6562f: Pull complete
Digest: sha256:6ec577d3b8ab0623bb60d4cedc5bcc4d9a1ee06e4dfe5ff2ff015d3d14d65f58
Status: Downloaded newer image for tomcat:9-jdk8-temurin-focal
docker.io/library/tomcat:9-jdk8-temurin-focal
#启动tomcat
[root@VM-16-10-centos home]# docker run -d -p 7777:8080 --name tomcat01 tomcat:9-jdk8-temurin-focal
77485b64c75fea0a836672b191e792c61378623dab100c9619174b948d902f6e
[root@VM-16-10-centos home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77485b64c75f tomcat:9-jdk8-temurin-focal "catalina.sh run" 2 minutes ago Up 2 minutes 0.0.0.0:7777->8080/tcp, :::7777->8080/tcp tomcat01
#将本地文件传到webapps下
[root@VM-16-10-centos home]# docker cp /home/WarmJava_war_exploded/ 77485b64c75f:/usr/local/tomcat/webapps
[root@VM-16-10-centos home]# docker exec -it tomcat01 /bin/bash
root@77485b64c75f:/usr/local/tomcat# ls webapps
WarmJava_war_exploded
访问题中路由并传参
成功反弹shell
用commit命令提交自己的镜像,可以方便以后的使用,或将镜像打包给其他人
#命令
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
测试
#启动之前的tomcat
[root@VM-16-10-centos ~]# docker start tomcat01
tomcat01
[root@VM-16-10-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77485b64c75f tomcat:9-jdk8-temurin-focal "catalina.sh run" 17 hours ago Up 3 seconds 0.0.0.0:7777->8080/tcp, :::7777->8080/tcp tomcat01
#commit 将修改好的tomcat打包
[root@VM-16-10-centos ~]# docker commit -m="Add Java Ctf" -a="Sentiment" 77485b64c75f tomcat1:1.0
sha256:8b280f81c6b1f788111844d60e6d21ae95b1fcaed2d4757a98a90b0eb18df497
#此时刚刚定义的tomcat1 成为了新的镜像
[root@VM-16-10-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat1 1.0 8b280f81c6b1 4 seconds ago 345MB
tomcat 9-jdk8-temurin-focal 05c35a4e6b74 4 days ago 342MB
方法一
命令挂载 -v
docker run it -v 主机目录:容器目录
#可以发现通过挂载后主机的home和docker容器中的home目录内容共享了
[root@VM-16-10-centos ~]# docker run -it -v /home:/home centos /bin/bash
[root@f6c0993fd2e5 /]# cd home
[root@f6c0993fd2e5 home]# ls
Sentiment.java WarmJava_war_exploded lighthouse www
[root@f6c0993fd2e5 home]# exit
exit
[root@VM-16-10-centos ~]# ls /home
lighthouse Sentiment.java WarmJava_war_exploded www
docker run -d -p 7777:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
挂载后此时在数据库中添加个test数据库,本地data中也就多了一个test目录
之后将数据库容器删除,但文件仍在本地保留
[root@VM-16-10-centos data]# docker rm -f mysql01
mysql01
[root@VM-16-10-centos data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6c0993fd2e5 centos "/bin/bash" 18 hours ago Exited (0) 18 hours ago ecstatic_vaughan
[root@VM-16-10-centos data]# ls
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql performance_schema public_key.pem server-key.pem test
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 mysql.sock private_key.pem server-cert.pem sys
[root@VM-16-10-centos ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
[root@VM-16-10-centos ~]# docker volume ls
DRIVER VOLUME NAME
local 674500de4c3a5a344fbac4b4e097b8c49c48c67a4787faf0aa9afc59c7c8d640
[root@VM-16-10-centos ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
b6ec76db6e9b5a5bb05ce4cb94ffc9ead91305680313d362817e71f38318cecc
[root@VM-16-10-centos ~]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
[root@VM-16-10-centos ~]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-09-10T16:09:42+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxx/_data
下
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用具名挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载
扩展:
# 通过 -v 容器内路径:ro rw改变读写权限
ro #只读
rw #可读可写
#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内无法操作
Dockerfile就是用来构建docker镜像的构建文件
#dockerfile内容 指令(大写)
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
执行dockerfile
启动自己写的容器
在卷中创建一个文件
[root@843d3ff7753c volume01]# touch test.txt
[root@843d3ff7753c volume01]# ls
test.txt
docker inspect 查看当前容器信息,发现了刚才挂载的两个卷
切换到volume01目录,发现刚才创建的文件
–volumes-from
启动容器docker02通过–volumes-from继承docker01的数据卷
此时如果在docker01的数据卷中创建文件,会直接共享到docker02的volume01中,并且这属于一种拷贝,当docker01被删除后docker02的数据仍然存在
构建步骤:
1、编写一个 dockerfile 文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库)
基础知识
1、每个保留关键字(指令)都必须是大写
2、执行从上到下顺序执行
3、#代表注释
4、每一个指令都会创建提交一个新的镜像层,并提交
FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 构建镜像的作者,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:tomcat镜像,这个tomncat压缩包,谭家内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 对外端口设置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被代替
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 Dockerfile 这个时候就会运行 ONBUILD 的命令,触发指令。
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置的环境变量
FROM centos
MAINTAINER Sentiment<1509041516@qq.com>
ENV MYPATH /usr/local
WORKDIR MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo ---- end ----
CMD /bin/bash
CMD测试
定义CMD后运行,直接输出了ls -a 的内容
若此时想追加l 即:ls -al,用cmd的方式只能替换:
docker run cmdtest ls -al
ENTRYPOINT测试
同理运行后执行ls -a
但此时若想 执行ls -al只需要在后边追加l即可:
docker run entrypoint-test -l
1、准备镜像文件tomcat压缩包和jdk压缩包
[root@VM-16-10-centos tomcat]# ls
apache-tomcat-9.0.65.tar.gz
jdk-8u65-linux-x64.tar.gz
2、编写dockerfile文件,官方命名问dockerfile
,使用该命名后build时会自动寻找这个文件,不再需要加- f
FROM centos
MAINTAINER sentiment<1509041516@qq.com>
ADD jdk-8u65-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.65.tar.gz /usr/local/
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_65
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.65
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.65
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.65/bin/startup.sh &&tail -F /usr/local/apache-tomcat-9.0.65/bin/logs/catalina.out
3、构建镜像
docker build -t idytomcat
4、启动镜像
docker run -d -p 4000:8080 --name sentimenttomcat -v /dockerfile/tomcat/test:/usr/local/apache-tomcat-9.0.65/webapps/test -v /dockerfile/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.65/logs diytomcat
5、访问4000端口测试
6、发布项目,在test目录下创建index.jsp和WEB-INF文件夹以及对应的web.xml
xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
web-app>
jsp
<html>
<head>
<title>Tomcattitle>
head>
<body>
<h2>Hi,Sentiment!h2>
body>
html>
此时访问test目录
docker login
输入账号密码后可以登录自己的dockerhub,之后就可以通过docker push
命令 上传我们的镜像
docker push sentiment/diytomcat:1.0
The push refers to repository [docker.io/sentiment/diytomcat]
An image does not exist locally with the tag: sentiment/diytomcat
这里报错 tag有问题,所以尝试修改一下,修改后成功上传
先清除所有镜像和容器
docker rmi -f $(docker images -aq)
docker ps -a -q|xargs docker rm
启动一个tomcat容器,查看IP地址
#启动docker容器
[root@VM-16-10-centos /]# docker run -d -P --name=tomcat01 tomcat
#执行ip addr后报错:没有命令
[root@VM-16-10-centos /]# docker exec -it tomcat01 ip addr
OCI runtime exec failed: exec failed: unable to start container process: exec: "ip": executable file not found in $PATH: unknown
#所以先进入容器,下载基础命令
[root@VM-16-10-centos /]# docker exec -it tomcat01 /bin/bash
root@6cd0a231ba62:/usr/local/tomcat# ip addr
bash: ip: command not found
root@6cd0a231ba62:/usr/local/tomcat# apt update && apt install -y iproute2
此时执行ip addr,发现了两个地址 lo 和eth0,其中eth0就是docker为各容器分配的,可以看到 docker0的ip地址为:172.17.0.1 ,启动的tomcat01容器分配的地址为:172.17.0.2,这两个ip在同一网段。
此时用本机ping容器,发现也是可以ping通的
再输入 ip addr 可以发现多了一对网卡和上面启动的tomcat01容器相对应
网络模型
02ping03时,相当于通过01路由器转发到了03
容器之间通过ip地址能ping通,但是通过容器名是无法ping通的
所以这时就需要使用–link解决此问题
docker run -d -P --name tomcat03 --link tomcat02 tomcat
此时03就能通过容器名ping通02了,但是02不能ping03,后来查看hosts文件发现是因为03的hosts文件中写入了02所以能ping通
查看docker中的所有网络
#通过命令创建一个自己的网络
[root@VM-16-10-centos ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
ed14e1ecebb9c311ddecc3670f5c6e0429e84a46181ccbf9ff997e6ec9c07441
#查看网络
[root@VM-16-10-centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
760dea8f9135 bridge bridge local
fa5c4ad578ff host host local
ed14e1ecebb9 mynet bridge local
531177f2dd44 none null local
#查看网络配置
[root@VM-16-10-centos ~]# docker network inspect mynet
#使用自定义网络创建容器
[root@VM-16-10-centos ~]# docker run -d -P --name=tomcat01-net --net mynet tomcat
4af4c548f11381f6fcf736d2fa5417ca216d134bc51635fc1aa681cde8f4fc02
[root@VM-16-10-centos ~]# docker run -d -P --name=tomcat02-net --net mynet tomcat
cf59546f20cbfd9c660142f5464a95250b7aa6e0bb1b872245a88a3cc1f6636e
通过自定义网络方式,能直接实现容器间的网络连接,就不在需要通过–link,
docker exec -it tomcat01-net ping tomcat02-net
启动之前定义的docker0网络镜像tomcat03
此时用tomcat03 ping mynet网络的容器是ping不通的,但是可以通过 connect命令进行连通
#connect连通
docker network connect mynet tomcat03
#ping测试
docker exec -it tomcat03 ping tomcat01-net
PING tomcat01-net (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.101 ms
64 bytes from tomcat01-net.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.066 ms
此时执行docker network inspect mynet
,发现mynet中多了tomcat03的网络