一、常用命令
1.帮助命令
systemctl start docker #在linux系统下开启docker服务
docker version #查看版本信息
docker info #详情信息,包括镜像和容器的数量
docker 命令 --help #查询帮助命令
帮助文档的地址:dockerd | Docker Documentation
2.镜像命令
查看已安装的镜像
docker images #查看所有本地主机上的镜像
docker images -a #列出所有镜像,启动过后关闭的镜像也会显示
docker images -q #只显示镜像id
[root@localhost /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest ea335eea17ab 10 days ago 141MB
centos latest 5d0da3dc9764 2 months ago 231MB#解释
REPOSITORY: 镜像的仓库源
TAG: 镜像的标签
IMAGE ID: 镜像的ID
CREATED: 镜像的创建时间
SIZE: 镜像的大小
搜索镜像
docker search [image] #搜索应用镜像
===> docker search mysql
#可选项,通过搜索来过滤
--filter=STARS=3000 #搜索出来的镜像STARS大于3000
[root@localhost /]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a … 11736 [OK]
mariadb MariaDB Server … 4476 [OK]mysql/mysql-server Optimized… 875 [OK]
.............
下载镜像
docker pull [image] #下载镜像
===> docker pull mysql #默认为最新版
docker pull mysql:8.0 #指定下载的版本8.0
docker 下载为分层下载,可以共用下载层,下载的镜像版本要为docker官网上的镜像版本,不然无法下载。
镜像版本官网:Docker Hub
删除镜像
docker rmi [镜像id/name] #删除指定镜像
docker rmi -f [镜像id/name] #强制删除镜像
docker rmi -f [镜像id/name] [镜像id/name] #强制多个镜像删除
docker rmi -f $(docker images -aq) #删除全部容器,$(...)中,可以执行命令
3.容器命令
说明:我们有了镜像才能创建容器,可以下载一个centos来学习
docker pull centos
创建容器
docker run [可选参数] image #新建容器并启动
#参数说明
--name "Name" 容器名字,用来区分容器
-d 以后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器端口:-p 8080:8080
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p 随机指定窗口
运行并创建容器
docker run -it centos /bin/bash #启动并进入centos容器
查看容器
docker ps #查看所有运行中的容器
docker ps -a #所有包括历史运行过的容器
docker ps -n=[个数] #显示最近创建的容器
docker ps -aq #显示所有容器的编号
退出容器
exit #容器停止并退出
Ctrl + P + Q 快捷键 #容器不停止,并退出
删除容器
docker rm [容器id] #删除一个容器,强制删除使用 -f
docker rm $(docker ps -aq) #删除所有容器
docker ps -aq|xargs docker rm #删除所有容器,运用管道的方式
启动与停止容器
docker start [容器id] #启动容器
docker restart [容器id] #重启容器
docker stop [容器id] #停止当前正在运行的容器
docker kill [容器id] #强制停止当前容器
4.常用的其它命令
后台启动容器
docker run -d centos #后台方式启动容器
问题:容器启动后,容器直接停止了,docker 容器使用后台运行时,必须需要一个前台进程,docker 发现没有应用时,会自动停止。
查看日志
docker logs [容器id] #查看日志
docker logs -f -t --tail [容器id] #查看日志,-t 日志加时间,-f 保留打印窗口,持续打印
docker logs -f -t --tail 10 [容器id] #查看最新的十条日志
查看容器中的进程信息
docker top [容器id]
查看镜像的元数据
docker inspect [容器id]
进入当前的容器
docker exec -it [容器id] /bin/bash #进入容器,开启一个新的窗口(终端)
docker attach [容器id] #进入容器,进入当前运行的窗口(终端)
从容器内拷贝文件到主机上
docker cp [容器id]:[容器内文件路径] [主机的目的路径]
5、尝试部署容器
以nginx为例:
docker search nginx #搜索需要部署的容器
docker pull nginx #下载需要部署的容器
#以后台方式启动nginx容器,名称为nginx01,外网访问端口号为3344映射nginx端口号为80
docker run -d --name nginx01 -p 3344:80 nginx
curl localhost:3344 #测试3344端口,是否为nginx
docker exec -it nginx01 /bin/bash #进入nginx容器
二、docker镜像
commit镜像
docker commit #提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" [容器id] [目标镜像名]:[TAG]
实战测试
以tomcat为例:
docker pull tomcat #下载tomcat容器
docker run -it -p 8080:8080 tomcat #启动并创建以交互的方式创建tomcat容器
[root@localhost ~]# docker run -it -p 8080:8080 tomcat
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/openjdk-11
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
28-Nov-2021 10:03:15.428 INFO [main]
........
关闭linux防火墙,使之可以在另一个客户端访问
#查看防火状态
systemctl status firewalld
service iptables status
#暂时关闭防火墙
systemctl stop firewalld
service iptables stop
#永久关闭防火墙,重启后生效
systemctl disable firewalld
chkconfig iptables off
#重启防火墙
systemctl enable firewalld
service iptables restart
再打开另一个窗口
docker exec -it [tomcat容器id] /bin/bash #进入tomcat容器文件
cp -r webapps.dist/* webapps #把文件复制
因为在tomcat默认文件中,没有原始项目,原始项目放在webapps.dist中,而启动项目包在webapps中,把默认项目放入启动项目包中则可以在另一个客户端访问docker容器项目
我们改变了tomcat文件中的webapps文件,现在把修改好的tomcat提交到docker镜像中
[root@localhost ~]# docker ps #查看当前的tomcat容器的id
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcec98319bec tomcat "catalina.sh run" 19 minutes ago Up 19 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp cool_pasteur
#进行提交
docker commit -a="walmxliove" -m="add webapps app" dcec98319bec tomcat01:1.0
[root@localhost ~]# docker images #查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat01 1.0 f10ac5dd5e80 4 seconds ago 684MB
tomcat latest 904a98253fbf 9 days ago 680MB
nginx latest ea335eea17ab 11 days ago 141MB
centos latest 5d0da3dc9764 2 months ago 231MB
===>这里已经入门docker了<===
三、容器数据卷
卷技术:目录的挂载,将容器挂载在宿主机上面
容器的持久化和同步操作,防止容器删除后,数据丢失!!!
使用数据卷
使用命令方式来挂载 -v
docker run -it -v [主机目录]:[容器内目录]
#测试:
docker run -it -v /home/ceshi:/home centos /bin/bash
容器内的文件:
[root@f0e87c0b795f /]# cd home
[root@f0e87c0b795f home]# touch test.txt
linux主机的文件:
[root@localhost home]# ls
ceshi walmxliove
[root@localhost home]# cd ceshi/
[root@localhost ceshi]# ls
test.txt
当容器内外产生映射的文件路径时,容器里相应映射的文件路径里的文件变化会同时linux主机相应文件路径会同时改变。
实战:安装mysql
docker pull mysql:5.7 #获取mysql8.0
#运行容器需要做数据挂载,安装启动mysql,需要配置密码!!!
#启动下载好的容器
docker run -d -p 3310: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
参数:
-d 后台启动
-p 端口映射
-v 卷挂载
--name 容器名称
外部软件尝试连接容器中的数据库:
OKOKOKOKOK!!!!
匿名挂载和具名挂载
匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /ect/nginx nginx
使用命令:docker volume ls 查看本地的镜像
查看出的镜像,就为匿名挂载,我们在 -v 只写了容器内路径,没有写容器外的路径!!!
具名挂载
-v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
图:显示了名字!!
所有的docker容器内的卷,没有指定目录的情况下都是在:
/var/lib/docker/volumes/[卷名xxx]/_data
我们通过具名挂载可以方便的找到我们的卷,大多数情况下都是使用 具名挂载
如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载
扩展:
什么意思???
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 readonly #只读
rw readwrite #可读可写
容器权限!!!(ro 只能通过宿主机操作,容器内部无法操作)
初识dockerfile
dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
先来写一个脚本看看:
创建一个文件:vim dockerfile01,编写内容:
#指令大写
FROM centos
VOLUME ["volume01","volume02"] #挂载目录文件,在容器内根目录下
CMD echo "-----end-----"
CMD /bin/bash
输入命令:
docker build -f dockerfile01 -t test-centos:1.0 .
[root@localhost docker-test-volume]# docker build -f dockerfile01 -t test-centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in aef5ffa89cf5
Removing intermediate container aef5ffa89cf5
---> 9a6a578ffc89
Step 3/4 : CMD echo "-----end-----"
---> Running in fb9ecf515afd
Removing intermediate container fb9ecf515afd
---> 52e2f2e12721
Step 4/4 : CMD /bin/bash
---> Running in 8b708586dbf3
Removing intermediate container 8b708586dbf3
---> f6e52ea28044
Successfully built f6e52ea28044
Successfully tagged test-centos:1.0
数据卷容器
实现数据在容器与容器间同步
实现:
先创建两个centos容器:
#第一个centos容器
docker run -it --name docker01 test-centos:1.0
#第二个centos容器,同时把这个容器挂载在第一个容器上
docker run -it --name docker02 --volumes-from docker01 test-centos:1.0
docker run -it --name docker02 --volumes-from docker01 test-centos:1.0
--volumes-from : 参数表示:把 docker02 挂载在 docker01 上 ,匿名挂载!!
测试数据是否同步:
在docker01容器中,挂载目录下创建一个test.txt文件
同时查看docker02:
成功!!!!!两个容器中的,挂载目录中的数据实现同步了!!!
结论:
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
容器删除后,挂载在本地的数据不会被删除!
四、DockerFile
DockerFile介绍
dockerfile 是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
- 编写一个dockerfile文件
- docker build 构建成为一个镜像
- docker run 运行镜像
- docker push 发布镜像(DockerHub,阿里云镜像仓库)
看看官方镜像:
很多时候,我们通常会搭建自己的镜像
DockerFile构建过程
基础知识:
- 每个保留关键字(指令)都必须时大写字母
- 执行从上到下顺序执行
- # 表示注解
- 每一个指令都会创建提交一个新的镜像层,并提交!
dockerfile 是面向开发的!!!
DockerFile 指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像作者,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #添加的内容
WORKDIR #镜像的工作目录
VOLUME #挂载目录
EXPOSE #指定暴露端口
CMD #指定这个容器启动的时候要运行的命令,只要最后一个会生效,会被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以终端追加命令
ONBUILD #当构建一个被继承 dockerfile 这个时候会运行 ONBUILD 指令
COPY #将文件拷贝到镜像中
ENV #构建时,设置环境变量
docker history [镜像id] #查看镜像生成步骤
构建实战测试
#1.构建一个自己的centos,创建一个文件,填入以下信息:
FROM centos
MAINTAINER walmxliove<123456@qq.com>ENV MYPATH /usr/local
WORKDIR $MYPATH #设置工作目录RUN yum -y install vim #在容器中运行 yum -y install vim 命令
RUN yum -y install net-tools #在容器中运行 yum -y install net-tools 命令EXPOSE 80 #暴露的端口
CMD echo $MYPATH #控制台打印,$MYPATH
CMD echo "-----end-----"
CMD /bin/bash#2.构建
docker build -f [文件路径] -t [镜像名]:[tag] .
docker build -f mydockerfile -t mycentos:0.1 .
#3.测试运行
成功!!!!
实战:Tomcat镜像
准备安装包:apache-tomcat-9.0.55.tar.gz jdk-8u311-linux-x64.tar.gz
编写dockerfile
FROM centos
MAINTAINER walmxliove<123445@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u311-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.55.tar.gz /usr/local/RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_311
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.55
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.55/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.55/bin/logs/catalina.out
构建命令:
docker build -t dockerfile .
启动容器并进行挂载:
docker run -d -p 9090:8080 --name studytomcat -v /home/tomcat/test:/usr/local/apache-tomcat-9.0.55/webapps/test -v /home/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.55/logs dockerfile
测试tomcat服务:
curl localhost:9090
显示如下信息:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Apache Tomcat/9.0.55</title>
.......................................................
</html>
尝试放入一个jsp页面:
因为tomcat容器中的webapps目录和宿主机挂载了,则可以在宿主机里放入相应的网页,则容器中会进行同步
cd /home/tomcat/test #进入挂载的目录
mkdir WEB-INF #创建web-inf 文件
vim web.xml #创建web.xml文件,并写入内容
<?xml version="1.0" encoding="UTF-8"?>
<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_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
cd .. #返回上一层级
vim index.jsp #编写jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>docker!!!! </title>
</head>
<body>
Hello World!<br/>
<h1>来自星星的你!!! </h1>
</body>
</html>
在url地址输入相应路径:
成功!!!!
注意:环境变量的配置以及最后的服务启动路径,配置出错时!tomcat服务启动不了,则容器则会无法后台模式启动,因为后台启动后,没有服务运行,容器会自动关闭!!!
发布自己的镜像
发布在DockerHub上
需要docker账号!!!
docker login -u [账号名] #登录docker账号
登录成功信息如下:
docker tag [镜像id/镜像名:tag] 新镜像名:tag #改镜像名,镜像名要规范
docker push [新镜像名]:tag #上传镜像
docker tag dockerfile walmxliove/centos-tomcat:1.0 #改镜像名,镜像名要规范
docker push walmxliove/centos-tomcat:1.0 #上传镜像
成功!!!
发布在阿里云上
- 登录阿里云
- 找到容器镜像服务
- 开启个人实例
- 创建命名空间
- 创建镜像仓库
- 查看仓库信息
出错就重启docker
#登录阿里云
docker login --username=walmxl**** registry.cn-hangzhou.aliyuncs.com
使用官方推荐的方法,把需要推送的镜像变成阿里云仓库规范的名字:
docker tag c61f77c4018c registry.cn-hangzhou.aliyuncs.com/study-walmxliove/test-walmxliove:1.0-centos-tomcat
进行推送:
docker push registry.cn-hangzhou.aliyuncs.com/study-walmxliove/test-walmxliove:1.0-centos-tomcat
成功!!!
五、Docker网络
ip addr #容器内部使用,可以查看容器ip地址
如果容器内部没有命令,则需要在容器内运行:
apt-get update
apt-get install -y iproute2
docker使用的是 linux 的网络桥接技术,每个容器都有一个由docker分配的ip地址,通过ip地址与docker通信,而每一个容器都可以和docker通信,则可以形成容器与容器之间通信。docker中的所有网络接口都是虚拟的。虚拟的转发效率高!!!
linux 可以直接 ping 通容器
--link 技术
不用通过ip地址,通过名字来访问容器,因为容器每次启动,都会分配ip,ip每次分配可能不一样!!!而名字则不变!!!
创建两个容器,以tomcat 为例:
尝试tomcat01 连接 tomcat02
注意:容器可能没有ping命令,则需要在容器内输入以下指令
apt-get update
apt install iputils-ping
apt install net-tools
则就可以运行ping命令了!!!!
使用 --link ,tomcat03 就可以 ping tomcat02 ,通过容器名!!! 是单向的!!!
docker run -d -P --name tomcat03 --link tomcat02 tomcat
本质:--link 就是我们在hosts配置中增加了一个 ip 映射 !!! /etc/hosts
自定义网络(常用)
docker network ls #查看所有的docker网络
网络模式:
bridge:桥接 docker(默认,推荐)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通!(局限性大)
测试
docker run -d -P --name tomcat01 --net bridge tomcat
我们可以自定义一个网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
查看自己的网络
把容器启动在自己的网络上
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
再次测试ping连接
可以通过容器名进行ping连接!!!!
可以使不同的集群使用不同的网络,保证集群的安全和健康!!!
网络连接
测试,容器与另一个网络连接
docker network connect mynet tomcat01
连通之后,就是讲tomcat01 放到了 mynet 网络下
一个容器,两个ip地址!!!!!
跨网络连接!!!
实战:部署redis集群
说明:三个redis集群,三个主结点,分别对应三个从结点!
使用脚本,创建6个redis,配置文件!!!,开启6个redis容器!!!
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >>/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
把${port} 换成1 ~ 6 逐一运行!!!
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
得:
进入一个redis容器中,进行集群配置:
docker exec -it redis-1 /bin/sh #进入redis-1中
#在redis-1中输入
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:637
9 --cluster-replicas 1
测试集群(在redis容器中):
redis-cli -c #以集群的方式启动!!!
127.0.0.1:6379> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3 #三个集群 !!!
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:625
cluster_stats_messages_pong_sent:607
cluster_stats_messages_sent:1232
cluster_stats_messages_ping_received:602
cluster_stats_messages_pong_received:625
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1232
设置值
127.0.0.1:6379> set a b
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
测试当,172.38.0.13 为ip的结点宕机时的效果:
成功!!!
六、把SpringBoot微服务打包成Docker镜像
- 构建springnboot项目
- 打包应用
- 编写dockerfile
- 构建镜像
- 发布运行
把jar包与Dockerfile传入linux里
docker build -t dream . #构建docker镜像文件
docker run -d -P --name dream-web dream #执行docker镜像
查看网页
成功!!!
接下来还需要学:Docker Compose , Docker Swarm , CI/CD之Jenkins