Docker学习笔记
Docker学习笔记
安装docker
卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
设置存储库
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 设置国内镜像库
docker version # 查看一下安装版本测试是否安装成功
启动 Docker
systemctl start docker
通过运行hello-world 映像验证 Docker Engine 是否已正确安装
docker run hello-world
镜像内默认端口号
MySQL 3306
nginx 80
docker常用命令
帮助命令
docker version #显示docker的版本信息
docker info #显示docker的系统信息,包括镜像和容器的数量
docker [命令] --help #帮助命令
镜像命令(image)
#解释
REPOSITORY #镜像的仓库源
TAG #镜像标签
IMAGE ID #镜像id
CREATED #镜像创建时间
SIZE #镜像的大小
#可选项
-a,--all #列出所有的镜像
-q,--quiet #只显示镜像的id
docker search #搜索镜像
#可选项,通过搜索来过滤
--filter=STARS=3000 #搜索镜像的stars大于3000的镜像
docker pull #下载镜像
docker pull 镜像名[:tag] #如果不写tag,默认下载最新版本[latest]
分层下载:dockers image 的核心,联合文件系统
docker pull mysql
docker pull docker.io/library/mysql:latest #两条命令等价
#指定版本下载
docker pull mysql:5.7
docker rmi #删除镜像[remove image]
-f [image id] #删除指定的镜像
-f [image id] [image id] [image id] #删除多个镜像
docker rmi -f $(docker images -aq) #导入[$(docker images -aq)]参数,查找所有的镜像,递归删除
docker history #镜像构建的历史信息
容器命令(container)
下载一个centos镜像来测试
docker pull centos
docker run [可选参数] image #新建容器并启动
#参数
--name="Name" #容器名字 tomcat01 tomcat02,用于区分容器
--net #指定IP
-d #后台方式运行
-i,-t #使用交互方式运行,进入容器查看内容
-p #指定容器的端口 -P 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口
-p 容器端口
容器端口
-P[大写] #随机指定端口
-e #环境配置
-v #卷挂载
docker run -it centos /bin/bash #进入centos容器
exit #退出容器
Ctrl + P + Q #容器不停止退出[大写模式]
docker ps #列出当前正在运行的容器
-a #列出全部容器,包括曾经运行过的
-n=? #显示最近创建的?个容器
-q #只显示容器的编号
dockers rm #删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,rm -f 强制删除
docker rm -f $(docker ps -aq) #删除所有的容器
docker rm -a -q|xargs docker rm #通过管道操作删除所有的容器
启动和停止容器的操作
docker start 容器id #启动
docker restart 容器id #重启
docker stop 容器id #停止
docker kill 容器id #强制停止
常用的其他命令
后台启动容器
docker run -d centos #后台启动centos
docker ps #centos停止了
#!!!docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
#!!!nginx,容器启动后,发现自己没有提供服务,就会立即停止
docker logs 容器id #查看日志
-f,-full #显示所有
-t,--timetamps #显示时间戳
--tail number #显示number条日志
自己编写一段shell脚本[!!!死循环]
docker run -d centos /bin/sh -c "while true;do echo 123456;sleep 1;done"
docker top 容器id #查看容器中的进程信息 [Linux中用ps]
#解释
UID #当前的用户id
PID #副id
PPID #进程id
docker inspect 容器id #查看镜像的元数据
docker exec或attach #进入当前正在运行的容器
#通常容器使用后台方式运行,需要进入容器,修改一些配置
#方式一
#命令
docker exec -it 容器id bashShell
#测试
docker exec -it 容器id /bin/bash
#方式二
docker attach 容器id
#测试
docker attach 容器id
#结果
正在执行当前代码......
docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)
docker attach #进入容器正在执行的终端,不会启动新的进程
docker cp 容器id:目录/文件 /主机目标目录 #从容器内拷贝到主机上
docker attach 容器id #进入容器
cd /home
ls
touch test.java #创建一个Java文件
exit #退出容器
docker ps -a
docker cp 容器id:home/test.java /home
#把容器中home目录下的test.java文件拷贝到主机的home目录下
#拷贝是一个手动的过程,之后可以使用 -v 卷的技术,可以实现,自动同步
小结
![](C:\Users\DELL\Pictures\Camera Roll\untitled.png)
练习
docker安装nginx
#搜索镜像
docker search nginx
#下载镜像
docker pull nginx
#查看镜像
docker images
#启动nginx容器
#docker run -d [--name nginx01] [-p:3306:80] nginx
#查看正在运行的容器
docker ps
#测试
curl localhost:3306
docker安装mindoc
#参考网址
https://github.com/mindoc-org/mindoc
DB_ADAPTER 指定DB类型(默认为sqlite)
MYSQL_PORT_3306_TCP_ADDR MySQL地址
MYSQL_PORT_3306_TCP_PORT MySQL端口号
MYSQL_INSTANCE_NAME MySQL数据库名称
MYSQL_USERNAME MySQL账号
MYSQL_PASSWORD MySQL密码
HTTP_PORT 程序监听的端口号
MINDOC_ENABLE_EXPORT 开启导出(默认为false)
#参考
export MINDOC=/home/ubuntu/mindoc-docker
docker run -it --name=mindoc2 --restart=always -v "${MINDOC}":"/mindoc-sync-host" -p 8181:8181 -e MINDOC_ENABLE_EXPORT=true -d registry.cn-hangzhou.aliyuncs.com/mindoc-org/mindoc:v2.1-beta.5
#实际运行代码
docker run -p 8181:8181 --name mindoc2 --restart=always -v /home/app/mindoc-sync-host:/mindoc-sync-host -e MYSQL_PORT_3306_TCP_ADDR=192.168.xxx.xxx -e MYSQL_PORT_3306_TCP_PORT=13306 -e MYSQL_INSTANCE_NAME=mindoc2 -e MYSQL_USERNAME=root -e MYSQL_PASSWORD=xxxxxx -e httpport=8181 -d registry.cn-hangzhou.aliyuncs.com/mindoc-org/mindoc:v2.1-beta.5
docker镜像
commit镜像
docker commit #提交容器为一个新的镜像
#命令
docker commit -m="描述的信息" -a="作者" 容器id 新镜像名称:[TAG]
容器数据卷
容器的持久化和同步操作,容器间也是可以数据共享的!
docker run -v 主机目录:容器内目录 #指定路径挂载
#执行后可以通过inspect查看元数据
docker inspect 容器id
元数据中"Mounts"中就是挂载的目录
docker volume 卷操作
create #创建一个卷
inspect #查看卷的数据
ls #列出
prune #移除所有没有使用的卷
rm #移除一个或多个卷
具名和和匿名挂载
#匿名挂载,不指定挂载的主机目录
-v 容器内路径
#具名挂载
-v 卷名:容器内路径
所有的docker容器内的卷,没有指定目录的情况下,挂载的文件都是在: /var/lib/docker/volumes/卷名/_data
拓展
#通过 -v 容器内路径:ro rw 改变读写权限
ro #readonly 只读
rw #readwrite 可读可写
#一旦设置了ro只读权限,容器内对于挂载出来的目录,在容器内就不可以改变了,只能通过外部改变
初识Dockerfile
dockerfile 就是用来构建docker镜像的构建文件,命令脚本
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层
#测试
在/home下mkdir docker-test-volume
cd docker-test-volume
vim dockerfile1
FROM centos #基础环境
VOLUME["volume1","volume2"]
#挂载,匿名挂载,容器内生成volume1和volume2,对应的容器外部目录可以通过docker inspect centos查看Mounts下的Source
CMD echo "-----end-----" #输出end分割线
CMD /bin/bash #进入镜像后走bash控制台
#-f 脚本的地址 -t 镜像名称 . 当前目录
docker build -f /home/docker-test-volume/dockerfile1 -t centos:1.0 .
数据卷容器
容器间同步,例如多个mysql同步数据
双向拷贝,只要有一个容器还在,数据就不会消失
#测试
docker run -it --name docker01 centos:1.0 #docker01父容器
Ctrl + p + q 退出当前容器,不关闭容器
#--volumes-from 类似Java中的继承,这里的docker01称为数据卷容器
docker run -it --name docker02 --volumes-from docker01 centos:1.0
Dockerfile
1.编写一个dockerfile文件
2.docker build 构建成为一个镜像
3.docker run 运行镜像创建容器
4.docker push 发布镜像(Docker Hub、阿里云镜像仓库...)
dockerfile构建过程
tips:
1.每一个保留关键字(指令)都必须是大写字母
2.指令是从上到下的顺序执行的
3.#表示注释
4.每一个指令都会创建提交一个新的镜像层
dockerfile的指令
FROM #基础镜像,一切从这里开始构建 (最基础的镜像:scratch)
MAINTAINER #维护者信息
RUN #镜像构建的时候需要运行的命令(在命令前面加上RUN即可)
ADD #添加要按照的应用的压缩包(COPY文件,自动解压)
WORKDIR #镜像的工作目录(/bin/bash)
VOLUME #挂载的目录
EXPOSE #暴露端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #但构建一个被继承的dockerfile,这个时候就会运行,触发指令
COPY #将文件拷贝到镜像中
ENV #构建的时候设置环境变量
CMD和ENTRYPOINT的区别
#测试CMD
#构建dockerfile
vim dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
#构建镜像
docker build -f dockerfile-cmd-test -t cmdtest
#运行镜像,ls -a 命令生效,列出所有文件
#想追加一个命令 -l(ls -al)
docker run 镜像id -l
#报错,-l替换了ls -a ,-l不是命令
#测试ENTRYPOINT
#构建dockerfile
vim dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls","-a"]
#构建镜像
docker build -f dockerfile-entrypoint-test -t entrypoint-test
#运行镜像,ls -a 命令生效,列出所有文件
#追加命令-l,成功
docker run 镜像id -l
实战:Tomcat镜像
1.准备镜像文件 Tomcat压缩包,jdk压缩包
2.编写dockerfile文件,可命名为Dockerfile(官方指定),build时会自动寻找这个文件,不需要加-f参数
FROM centos
MAINTAINER wyx<12345678@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8ull-linux-x64.tar.gz(自动解压)
ADD apache-tomcat-9.0.22.tar.gz
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080(设置暴露端口)
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh &&(拼接) tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
3.构建镜像
docker build -t testcomcat .
4.创建容器
docker run -d -p 9090:8080 --name comcat01 -v 本地目录/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v 本地目录/tomcatlogs/://usr/local/apache-tomcat-9.0.22/logs testcomcat
5.创建成功后,容器外执行curl localhost:9090,验证是否可以访问
6.发布项目
本地修改文件即可
提交上传镜像
1.发布到官网镜像仓库
(1)注册dockerhub账号
(2)docker login -u 账号 -p 密码 docker logout 退出账号
(3)docker push 作者/testtomcat:[tag]
如果报错,有重复的镜像可以再加一个tag
docker tag 镜像id 新名称:[tag]
2.发表到阿里云镜像仓库
1.登录阿里云
2.找到容器镜像服务
3.创建命名空间
4.创建容器镜像
镜像打包
docker save 打包
docker load 加载
Docker网络
docker是如何处理容器网络访问的?
1.启动一个容器
docker run -d -P --name tomcat01 tomcat
docker exec -it 容器id ip addr #精简命令,不进入/bin/bash目录,直接执行ip addr
#容器启动后会得到一个eth0的IP地址,这是docker分配给容器的,Linux可以ping通
2.再启动一个tomcat02容器
原理:
我们每启动一个docker容器,docker就会给docker容器分配一个IP,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的是evth-pair技术
evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备
OpenStac,Docker 容器之间的连接,OVS的连接,都是使用 evth-pair 技术
3.测试tomcat01和tomcat02能否ping通
结论:容器和容器之间是可以ping通的
tomcat01和tomcat02是公用的一个docker0路由器,在不指定IP的情况下
docker中的所有的网络接口都是虚拟的,虚拟的转化效率高
--link #通过容器名称ping通
docker run -d -P --name tomcat03 --link tomcat01 tomcat
docker exec -it tomcat03 ping tomcat01
#反向连接不能ping通
#查看hosts配置,--link就是我们在hosts配置中增加了一个tomcat的ip和容器名称、id
docker exec -it tomcat03 cat /etc/hosts
现在使用docker已经不建议使用--link了,docker0的限制:不支持容器名连接访问
推荐使用自定义网络
docker network #自定义网络
connect #连接一个容器到一个网络
create #创建
disconnect
inspect #详情
ls #列出
prune #移除所有没有使用的网络
rm #移除
--net 指定网络模式或网络
# 网络模式
bridge #桥接,docker(默认),自己创建也选择桥接模式
none #不配置网络
host #主机模式,和Linux服务器共享网络
container #容器网络连通(局限大)
docker network create #创建一个网络
#直接启动的命令,默认--net bridge,而这个就是docker0
docker run -P -d --name tomcat01 --net bridge tomcat
#docker0特点,默认,域名不能访问,--link可以打通连接
docker network create [参数]#创建网络
-d,--driver #网络驱动类型(默认bridge)
--gateway #网关
--subnet #子网
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
docker rum -d -P --name tomcat-net-01 --net mynet tomcat
docker rum -d -P --name tomcat-net-02 --net mynet tomcat
#再次测试ping连接,不使用--link也可以通过容器名ping通
docker exec -it tomcat-net-01 ping tomcat-net-02
不同的集群使用不同的网络,保证集群的安全和健康
docker network connect 网络 容器名 #网络连通
#测试打通tomcat01和mynet
docker netwoek connect mynet tomcat01
docker network inspect mynet
#连通之后就是将tomcat01放到了mynet网络下,一个容器两个IP地址
#阿里云服务器:公网IP,私网IP