Docker详细教程——入门篇
官方地址
docker概念
概念:类似于各种项目和软件的应用商店,大家把项目放到docker仓库中也就是这个应用商店,其他人就可以下载使用这个项目,各个项目直接独立互不影响。使用docker只需要把我们的项目打包成镜像放到docker中。
相关概念
imag镜像
容器的模板,用来构建容器,相当于.class文件
container容器
一组组服务
repository仓库
镜像存放地址
docker底层操作流程
过程:client——》sever——》daemon守护进程——》容器
客户端通过连接docker server,server内部有一个守护进程,进程去连接各个容器,容器之间互相隔离
docker好处
高效运行,充分理由系统资源
docker容器实现的是内核共享,直接申请内核资源
高效运维
环境直接拷贝运行,不用重头在搭建
为什么比虚拟机快
直接操作内核不需要再原有的操作系统上在实例化一个操作系统,如下图所示
docker常用命令概览
client(build,pull,run,构建,拉取,启动容器)——>服务器,通过守护进程去操作镜像(相当于模板)生成一个个容器<—-repository远程仓库获取镜像的地方
docker安装
本教程环境
centOS7,内核3.0以上
查看内核版本
uname -a
查看centOS版本
cat /etc/os-release
安装步骤
docker engine安装官方文档
官网指南
1.卸载旧版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2.安装工具依赖
yum install -y yum-utils
3.更新yum工具
yum makecache fast
4.下载docker(默认最新,可指定版本)
yum install docker-ce docker-ce-cli containerd.io
5.启动docker
systemctl start docker
6.查看docker是否启动成功
docker version
注:出现版本号则启动成功
7.测试docker,启动一个hello world镜像
解决提示找不到软件包:添加阿里云镜像
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
镜像
镜像底层原理
docker的镜像为什么小,因为它底层很多模块是共用的,共用部分不会重复下载,通过分层的方式不断在这个镜像上去叠加应用,添加的应用又可以生成一个新的镜像。底层使用的联合文件系统UnionFS,可以简单理解为搭积木,不断在上面搭建你想要的应用。
如下图所示:
-
bootfs(boot file
system):docker镜像的最底层是bootfs,主要包含bootloader(加载器)和kernel(内核)。bootloader主要是引导加载kernel,linux刚启动时会加载bootfs文件系统。当bootfs加载完成后,整个内核就在内存中了,此时内存的使用权已由bootfs转交给了内核,此时系统也会卸载bootfs。
这里的加载,可以理解为,我们windows电脑开机时候,从黑屏到进入操作系统的过程。 -
rootfs(root file system):在bootfs之上,包含的就是典型linux系统中的/dev、/proc、/bin、/etc等标准目录和文件。不同的 Linux 发行版, boots 基本是一致的, rootfs 会有差別。
-
在上面两个基础上不断的叠加需要的镜像
镜像命令官方地址
查询命令
镜像命令
官方文档
所有命令可以使用–help命令查看解析
搜索镜像
docker search mysql[版本号]
拉取镜像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
搜索条件
tag版本获取在dockerhub上去找
镜像删除
docker image rm [image id]
官方文档
示例:使用image ID 删除
递归删除所有镜像
docker rmi -f $(docker images -qa)
docker将容器提交为一个镜像
docker commit -a=[authoer] -m=[descrip] [containerid] [my image name]:[tag]
批量删除镜像
docker rmi -f $(docker images -q)
容器
下载一个镜像生成去操作容器,这里以centos7为例子
1.在hub上找centos版本,使用该版本拉去images
创建容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
run的 options
-it 指定交互
-d 后台运行容器
docker run -d centos:7
问题:这样运行发现容器没有启动,原因是想centos这样的容器,docker会检查是否存在前端客户端,如果没有就会关闭
退出容器
退出后容器关闭exit
退出后容器不关闭
ctrl+p+q
重新进入容器
方法1:进入正在执行的终端
docker attach [imageID]
方法2:开启一个新的终端
docker exec-it [imageID] /bin/bash
删除容器
docker rm [OPTIONS] CONTAINER [CONTAINER...]
容器的启动和关闭
docker ps -a 查询出容器ID,然后根据ID启动和停止
docker start [容器ID]
docker stop [容器ID]
docker restart [容器ID]
查看容器进程
查询条件
查看容器内部进程
docker top [container id]
查看容器元数据
docker inspect [container id]
查看容器日志
sudo docker logs --tail=1000 容器ID
例子
docker logs --tf -tail 500f 54354542derf
从容器中拷贝文件到主机
docker cp [dockerID]:[docker path] [rootpath]
容器卷
匿名挂载
概述:不指定外部容器地址和名字,系统默认给你分配一个挂载地址
docker run -d -v /etc redis
docker inspect [contain id]
查看系统分配的主机挂载地址在哪里
具名挂载
概述:指定外部容器挂载文件的名字,系统默认给你分配一个我们名字命令的挂载地址
docker run -d -v test-redis:/etc redis
docker inspect [contain id]
路径挂载
概述:指定主机路径和内部容器的路径
docker run -d -v /home/testredis:/etc redis
docker inspect [contain id]
各个容器之间的文件共享
例如mysql,启动多个mysql,其它的mysql挂载的时候使用==–volumes-from [container name]==继承另外一个mysql的挂载地址就可以实现多个容器之间的数据共享,这个数据是存在本机上的,因此删除其他容器数据不会消失
docker run -it --name mysql-client --volumes-from server-game \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 \
/bin/bash /data/p-0/winner/ci/cleandb.sh
批量停止容器
docker stop $(docker ps -a -q)
批量删除容器
docker rm -f $(docker ps -a -q)
dockerFile
概述
dockerfile用来构建一个镜像,通过分层的方式一层一层的叠加
DockerFile命令解析
cmd和entrypoint和区别
我们在docker run [contain id] 后面添加命令的时候cmd是替换,entrypoint是追加,运行的时候不追加命令它们两个就没有区别
dockerFile实战——发布springboot项目
- 打成一个jar包
- 把jar包放到dockerfile放到某个同级目录下
- 运行build命令
docker build -f[dockerfile path] -t [image name] .
示例
sudo docker build -t test:1.0 .
- 运行容器
sudo docker run -d --name [容器名称] --net=host -p 8766:8766 --restart=always [镜像ID或者‘[镜像ID:版本号]’]
docker实战——安装redis
第一步在docker.hub上选择一个拉去redis的版本
docker pull redis:7.0.3
第二步创建容器和本地主机挂载文件路径
mkdir /home/redis/data
mkdir /home/redis/config
touch /home/redis/config/redis.conf
注:由于docker中的redis.conf默认没有,需要自己在官网找一个放上去
启动命令
docker run -p 6379:6379 --name redis -v /home/redis/conf/redis.conf:/etc/redis/redis.conf -v /home/redis/data:/data -d --restart always redis:7.0.3 redis-server /etc/redis/redis.conf --appendonly ye
参数解析
参数 | 说明 |
---|---|
appendonly | 开启redis 持久化 |
requirepass | 设置密码 |
–restart=always | 开机自启动 |
d redis redis-server /etc/redis/redis.conf | 后台启动,指定配置文件 |
开启远程访问,在配置文件中的bind 127.0.0.1注释即可
docker实战——安装mysql
1.拉取镜像
2.创建容器
docker run -itd --name mysql5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=密码 mysql:5.7 --lower_case_table_names=1 --max_connections=10000;
参数解析
lower_case_table_names=1:忽略大小写;
max_connections:最大连接数量;
–name:为容器指定一个名称,此处命名为mysql8.0
-e:配置信息,此处配置mysql的root用户的登陆密码
-p:端口映射,此处映射 主机3306端口 到 容器的3306端口
-d:后台运行容器,并返回容器ID;
进入mysql
docker exec -it [imageID] /bin/bash
docker实战——安装nginx
拉取镜像
创建需要挂载的文件夹
在指定路径创建html(可以放直接访问的静态页面),(运行日志)log,(放nginx.conf)conf
我是在/usr/local/nginx下创建的
把nginx,conf 上传到你创建的conf目录下
启动命令
docker run -d -p 80:80 --name nginx -v /usr/local/nginx/html:/usr/share/nginx/html -v /usr/local/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/nginx/logs:/var/log/nginx nginx
修改nginx.conf重启docker生效
sudo docker restart 容器ID
docker——安装vsftpd
ftp服务器的主动模式和被动模式区别
概述
主动模式,ftp客户端随机开放端口,ftp服务端使用固定端口去传输数据
被动模式:ftp服务器端数据开发端口。客户端连接这个端口进行传输数据
拉去镜像
sudo docker pull fauria/vsftpd
启动命令
sudo docker run -d -p 21:21 -p 20:20 -p 21100-21110:21100-21110 -v /home/ftp:/home/vsftpd/user1 -e FTP_USER=user1 -e FTP_PASS=pass123 -e LOCAL_UMASK=022 --name vsftpd --restart=always fauria/vsftpd
参数解析 参考文档
-d 使用 daemon 模式新建并启动容器,后面的 --restart=always 可以让容器在重启宿主时也一并启动容器
-p 21:21 -p 20:20 -p 21100-21110:21100-21110 这个是容器的端口映射,ftp 会使用命令端口(缺省为21)、数据端口(缺省为20)和被动模式端口(连续端口)三类
注意:不要重新映射被动模式端口段,否则连接 ftp 后连 ls 命令都会执行失败,如果宿主机端口段被占用,可以通过后面的 -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21110 来重新定义,并在 -p 21100-21110:21100-21110 内原样映射
-v /home/ftp:/home/vsftpd/user1 /home/ftp主机上文件存储的位置,/home/vsftpd/创建的用户名
-e FTP_USER= -e FTP_PASS= 增加 ftp 用户及其密码
-e PASV_ADDRESS=ftp服务器IP -e PASV_MIN_PORT=21100 -e PASV_MAX_PORT=21110 定义被动模式地址和端口
注意:被动模式地址一定要设置成访问者能看到的 IP,多IP尤其要注意
-e LOCAL_UMASK=022 定义新创建的子目录和文件应该去除的访问权限,这里是去除 user(无) group(write) other(write)权限,所以新建的目录和文件宿主机的用户可以读取无法写入
注意:如果没有加这条环境变量,新建的目录和文件权限为 700,宿主机的用户无法查看目录和读取文件。因为 vsftpd 其实是读取环境变量用来修改(容器内部)/etc/vsftpd/vsftpd.conf 内的 local_umask,其原始值为 local_umask=077,所以新建的目录和文件权限为 700,宿主机的用户因此无法查看目录和读取文件
–name vsftpd 为新容器起一个别名
fauria/vsftpd 是使用的 docker image 名字,如果本地没有缓存,会先去下载,使用 docker search vsftpd 搜索后发现这个 image stars 最多
结果展示
解决vsftpd客户端连接特别卡问题
安装好之后我发现这客户端连接非常卡
docker网络
先导
docker会为每个容器创建一个虚拟网卡
没有创建容器之前
创建容器之后
主机可以ping的通容器内部
容器之间也可以ping通
docker网络概述,为什么容器之间个主机之间可以ping的通
docker默认有一个虚拟路由docker0,容器之间个主机之间通过这个虚拟路由进行转发,相当于一个局域网
docker常见的网络模式
bridge:桥接模式(docker0就是这种模式)
none:不指定网络
host:共享主机网络
container:容器网络胡亮
docker 网络命令
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
查看所有docker网路
docker network ls
自己创建一个network,自己创建的network会自动维护网络关系,多个集群之间用不同的网段也保障了安全
自定义子网掩码和网关
docker network create --driver bridge --subnet 192.168.1.0/16 --gateway 192.168.1.0 mynet
运行一个tomcat容器使用–net指定网络
docker run -d -P --name="tomcat-mynet01" --net mynet tomcat
容器跨网络访问另外一个容器
使用mynet和docker0个启动两个tomcat
容器之间互相连接
无法使用ping命令怎么办?在容器内部安装命令
apt-get update
apt install net-tools # ifconfig
apt install iputils-ping # ping
没连接之前,同一网络的可以ping通,其他网段的ping不通
连接其它网段的容器
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
示例
docker network connect mynet tomcat03
通过connect命令可以看到mynet直接把tomcat03添加到元数据里面
docker搭建redis-cluster集群
参考这位老哥的博文,两个文件一下子搭好,10分钟不要
Docker搭建redis集群(三主三从)
下面简单介绍一些redis集群的几种模式
主从模式
一个master多个slave节点,主节点master挂掉以后,从节点提供读功能,只有master具备读写功能,当master挂掉以后只能等master恢复以后才能写。
哨兵模式
提供一组哨兵去监测master有没有挂掉,一半以上的哨兵发现master挂掉,其中的一个slave重新作为master,slave节点通过发布订阅的方式将其他节点的master信息修改掉。这种模式还是在master上进行读写因此也不具备高可用
cluster模式
redis3.0之后推出的高可用集群功能。客户端使用分片的方式去选择集群,一个redis-cluster集群有一个slot区域,客户端在连接集群的时候把集群中的这个slot分片文件缓存到本地,通过hash值对16384取模获取读写的区域。每个区域的redis都是主从结构,当master挂掉以后切换到slave,由于是分片集群,其中一个分区挂掉影响也较小,理论上是可以做16384分区,但是在实际应用中一般1000个分区就很大了,多了内网宽带负担很大。
安装docker可视化界面portainer管理docker
两步
docker pull portainer/portainer
docker run -p 9000:9000 -p 8000:8000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /mydata/portainer/data:/data \
-d portainer/portainer
访问地址:ip:9000
刚刚创建的redis集群成功