前提准备
- 腾讯云服务器
安装
参考官方文档
# 1.卸载旧版docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2.需要的安装包
sudo yum install -y yum-utils
# 3.设置镜像仓库
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# https://download.docker.com/linux/centos/docker-ce.repo // 官方文档是国外的镜像,慢
# 4.更新yum软件包索引
sudo yum makecache fast
# 5.安装Docker ce是社区版,ee是企业版
sudo yum install docker-ce docker-ce-cli containerd.io
# 6.启动Docker
sudo systemctl start docker
# 7.hello-world
sudo docker run hello-world
# 如何卸载docker
# 卸载依赖
sudo yum remove docker-ce docker-ce-cli containerd.io
# 删除资源
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Docker命令
帮助命令
docker version # docker版本信息
docker info # docker的系统信息,包括镜像合和容器数量
docker --help # 帮助命令
镜像命令
docker images # 本地镜像列表
docker search mysql # 相当于在dockerhub上搜索mysql
docker pull mysql 下载镜像
Using default tag: latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete # 分片下载
93619dbc5b36: Pull complete
99da31dd6142: Pull complete
626033c43d70: Pull complete
37d5d7efb64e: Pull complete
ac563158d721: Pull complete
d2ba16033dad: Pull complete
688ba7d5c01a: Pull complete
00e060b6d11d: Pull complete
1c04857f594f: Pull complete
4d7cfa90e6ea: Pull complete
e0431212d27d: Pull complete
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709 # 签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址,docker pull mysql 等价于 docker pull docker.io/library/mysql:latest
docker rmi 删除镜像
docker rmi -f 镜像id # 删除指定镜像
docker rmi -f $(docker images -aq) # 遍历删除全部的镜像
容器命令
说明:有了镜像才可以创建容器
接下来下载一个centos镜像来测试docker pull centos
新建容器并启动
docker run -it centos /bin/bash # -it是进入到容器中 -d是后台启动
退出容器
exit
ctr + P + Q # 退出不停止容器
列出容器
docker ps # 列出正在运行的容器
-a # 列出正在运行的容器+ 曾经运行过的容器
-n=1 # 列出最近创建的1个容器
-q # 只列出容器的编号
删除容器
docker rm 容器id # 删除容器 正在运行的容器要加 -f 才能删除
docker rm -f $(docker ps -aq) # 遍历删除所有容器
docker ps -a -q|xargs docker rm # 利用管道删除所有容器
启动/停止容器
docker start 容器id
docker restart 容器id
docker stop 容器id # docker stop,支持“优雅退出”。先发送SIGTERM信号,在一段时间之后(10s)再发送SIGKILL信号。Docker内部的应用程序可以接收SIGTERM信号,然后做一些“退出前工作”,比如保存状态、处理当前请求等。
docker kill 容器id # docker kill,发送SIGKILL信号,应用程序直接退出。
其他常用命令
后台启动容器
docker run -d 镜像id #后台启动容器 以centos为例,等价于docker run -d centos /bin/bash
# 问题: 执行docker ps 发现容器已经停止了
# docker容器使用后台运行,就必须有一个前台进程,docker发现没有应用,就会立即停止
查看日志
docker logs -tf 容器id
# 为了不让后台启动的容器自动停止,写入执行脚本
# docker run -d centos /bin/bash -c "while true;do echo longjun;sleep 1;done"
# docker logs 容器id # 不带参数获取执行时容器内输出的日志
# -t 显示日志输出时的时间
# -f 显示日志并持续获取后续输出的日志
# -n 10 获取10条日志
查看容器中进程信息
docker top 容器id
查看容器的元数据
docker inspect 容器id
进入当前运行的容器
docker exec -it 容器id bashShell # 比如 docker exec -it d019caf20711 /bin/bash #新开的终端
docker attach 容器id # 进入容器正在执行的终端
拷贝容器内文件到主机
docker cp 6e5e77da2b92:/home/helloworld.html /home # 将容器内/home/helloworld.html 文件拷贝到主机home文件夹内
docker内启动服务和主机端口联通
docker run -d -p 3355:8080 --name tomcat01 tomcat # 以tomcat为例 -p 3355:8080 就是把主机的3355端口和容器内的8080端口联通 注意需要放开主机防火墙的3355端口访问限制
# tomcat 镜像内webapps内没有内容,所以访问3355会显示http 404,需要进入容器,把webapps.dist文件夹内的所有文件复制到webapps中
docker exec -it tomcat01 /bin/bash
cp -r webapps.dist/* webapps
查看容器在主机的内存使用情况
docker stats
# 发现容器占用内存过大可以增加限制 如elasticsearch不加内存限制会达到2个多G,这里限制为64m-512m
# docker run -d --name elasticsearch01 --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.16.2
commit镜像
docker commit -a="longjun" -m="add webapps app" 容器id tomcat02:1.0 # 在本地生成一个新的镜像
使用数据卷
docker run -it -v /home/test:/home centos /bin/bash
# 以mysql为例使用数据卷
docker run -it -p 9001: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
# 注意mysql数据卷指向的主机目录/home/mysql/data内不能有mysql以外的内容,否则会报错
具名挂载和匿名挂载
docker run -d -P --name nginx01 -v /etc/nginx nginx
# -v 是挂载数据卷,一般冒号左侧目录是主机目录。冒号右侧目录是容器内目录,若只写一个目录则是容器内目录,主机目录由docker自动指定,这两种情况都是匿名挂载
# -P 当使用-P(大写)标记时,Docker会随机映射一个49000~49900的端口到内部容器开放的网络端口,端口可通过docker ps 查看
# 具名挂载:冒号左侧不是一个目录而是一个变量名 如 -v nginxVolume:/etc/nginx
docker volume ls # 查看所有的数据卷,匿名数据卷都是一长串编码
# DRIVER VOLUME NAME
# local 3a1d1b0c7a1ca986282ee7aaf7a298556a5950ae1c0f4b25dc0a61f798dd4405
# local 37b05298d0c351400d866ad24911be4b9a8f279d1753ea3f12593df5bf5feffd
# local 225ac2f0268f77162aa7a9acdd7794421fba3efccd4facba4dcf04be79462c07
# local 599ba7f25f38ffa4e6c4967d56661b60319be7e6982d10bedf3e95491a74eaa3
# local 652a535d96dffa856156b099caa4ea412667fec38c9143992af0d5a07362bea6
# local 08895be143b5f363344676415c099955ff2830a39a64f266479174b34431f3f0
# local d60138fe48ef1a46388fddf597c7c038b80a60949cc41aa989e4b86d2b5eb127
# local f31e8a47d00d9b47f14d61fab9d63bbeed5701ef28e8aef9214983fbe78e4f51
# local mingzi
docker volume inspect mingzi # 查看数据卷相关信息
# [
# {
# "CreatedAt": "2022-01-19T21:53:30+08:00",
# "Driver": "local",
# "Labels": null,
# "Mountpoint": "/var/lib/docker/volumes/mingzi/_data", # 数据卷主机目录,未指定主机目录的卷都会放在docker/volume目录下
# "Name": "mingzi",
# "Options": null,
# "Scope": "local"
# }
#]
DockerFile
dockerFile是用来构建镜像的构建文件。一个命令脚本,脚本的每一个命令就是镜像的一层
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "--------end--------"
CMD /bin/bash
以上就是一个简单的dockerFile文件,在构建时就指定了两个匿名卷要挂载到主机
数据卷容器
# 通过--volumes-from 指定共享数据的容器
docker run -it --volumes-from testDockerFile01 --name testDockerFile02 longjun/centos
DockerFile指令
FROM # 基础镜像
MAINTAINER # 镜像谁写的,姓名+邮箱
RUN # 镜像构建时需要运行的命令
CMD # 容器启动时要运行的命令,只有最后一个会生效,会被运行时的参数替换
ADD # 添加压缩包,如tomcat镜像
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
ENTRYPOINT # 指定容器启动时要运行的命令,可以追加命令,不会被运行时的参数替换
ONBUILD # 当构建一个被继承DockerFile时会允许ONBUILD的指令
COPY # 类似ADD,将文件拷贝到镜像中
ENV # 构建的时候设置环境变量
构建一个完整的centos
官方的centos只有基础的功能,没有vim,ifconfig等功能,可以自己构建一个
FROM centos
MAINTAINER longjun<228089xxxx@qq.com>
ENV MYPATH /user/local
WORKDIR $MYPATH # 设置工作目录(进入容器默认进入的目录)
RUN yum -y install vim # 安装vim
RUN yum -y install net-tools # 安装ifconfig相关的指令
EXPOSE 80
CMD echo $MYPATH
CMD echo "--------end--------"
CMD /bin/bash
CMD 和 ENTRYPOINT 的区别
- CMD命令运行时的参数会把它替换掉
- ENTRYPOINT命令可以在运行时通过参数追加,而不会被替换
# 测试dockerFile。将CMD替换为ENTRYPOINT对比测试,运行时增加参数 -l
FROM centos
CMD ["ls","-a"]
link 容器间网络互通
- 每创建一个容器docker0网络(172.17.0.1/16)都会给主机和该容器各分配置一个ip用于容器和主机的联通
- 容器间也可以通过容器的ip进行联通,但本质上还是经过主机桥接进行联通
- 通过容器名访问:通过 --link 容器2 可以直接通过容器名连通对应容器(其实就是在host配置中添加了容器2的ip),注意这里只是单向连通
自定义网络
查看所有网络docker network ls,docker0就是bridge(桥接)网络模式
NETWORK ID NAME DRIVER SCOPE
b6d5f1a29898 bridge bridge local
3203efb39ec4 host host local
7732bb6babe6 none null local
4e67d2610a72 somenetwork bridge local
--net bridge 正常启动一个容器会有默认参数--net bridge 即使用docker0网络,我们也可以改成我们自己创建的网络
创建自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gatway 192.168.0.1 mynet
# --driver bridge 使用桥接网络模式
# --subnet 192.168.0.0/16 子网网段192.168.0.2 - 192.168.255.255
# --gateway 192.168.0.1 网关
创建容器使用自定义网络
# 启动两个tomcat容器并连接mynet
docker run -d -P --name tomcat-net-01 --net mynet lj996/tomcat
docker run -d -P --name tomcat-net-02 --net mynet lj996/tomcat
查看mynet网络详细docker network inspect mynet
[
{
"Name": "mynet",
"Id": "d402792af1ad4cee67b934bb597377863a5d0cde4f61fe00c2eb513a2752a154",
"Created": "2022-02-19T11:32:13.820610538+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16", # 创建时设置的网段
"Gateway": "192.168.0.1" # 创建时设置的网关
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": { # 所有连接的容器ip明细
"1a9b96d7013c55e82cfc079f1714deb602a6fd751e63e91eccb109aba4c4e6ba": {
"Name": "tomcat-net-01",
"EndpointID": "7b607d9b7c49a302467cf21619d0612569233e21e6f92d83e0661882bcdde983",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"5bd3d0a7f87178c17fb9bfbe460601a17eb4393d18584568dbf91d0df3677c4d": {
"Name": "tomcat-net-02",
"EndpointID": "7378f6ad85a7cce79d9ffb00fb4fe8c07b8e8ba18853ea0df776e6268fdfcac0",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
容器连通
- 同网络容器连通 docker0网络容器间需要通过ip连通,或者使用--link才能通过容器名连通,而且还只是单向连通 自定义网络即能通过ip,也能通过容器名连通,无需--link
docker exec -it tomcat-net-01 ping tomcat-net-02
# ping不通应该是容器内没有ping命令,可以先进入容器安装apt-get update && apt-get install iputils-ping(由于docker在制作时,精简了apt的仓库信息。因此使用前需要update),安装完在ping就可以了
- 不同网络容器连通 通过docker0创建的容器和通过mynet创建的容器怎么连通呢,因为不同网段应该是不可能连通的
换个思路,既然不同网段不能连通,那就加入到同一个网段
# 先创建一个docker0网络的容器
docker run -d -P --name tomcat-01 lj996/tomcat
# 将tomcat-01容器和mynet网络连接
docker network connect mynet tomcat-01
此时容器tomcat-01同时在docker0和mynet网络中,有两个ip地址,这样该容器就能连通两个网络中所有的容器