typora开启关闭大纲快捷键:ctrl+shift+L或者ctrl+shift+1
跳转到文末:Ctrl+End
Docker
弱小和无知不是生存的障碍,傲慢才是
知道的越多,不知道的越多
即使再小的帆也能远航
Docker 核心思想:隔离
Docker历史
虚拟机和 Docker 容器技术都属于虚拟化技术
vm:linux centos 原生镜像(一个电脑),隔离需开启多个虚拟机,一个虚拟机几十个G,启动速度慢
Docker:隔离,镜像(最核心的环境 4m+jdk+mysql)十分小巧,几M,秒级启动
Docker 基于 GO 语言开发,开源项目
官网:https://www.docker.com/
文档地址:https://docs.docker.com/ 文档很详细
仓库地址:https://hub.docker.com/
Docker 作用
虚拟机技术
虚拟机技术缺点:
- 资源占用多
- 冗余步骤多
- 启动很慢
容器化技术
容器化技术模拟的不是一个完整的系统
两者不同:
- 传统虚拟机,虚拟出一套完整的硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内容上,容器时没有自己的内核的,也没有虚拟硬件,十分轻便
- 每个容器是相互隔离,没有容器内都有哦一个属于自己的文件系统,互不影响
DepOps(开发、运维)
应用更快速的交付和部署
更便捷的升级和扩缩容
更简单的运维
更高效的计算资源利用
Docker的基本组成
镜像:image
Docker 镜像就好比是一个模板,可以通过模板来创建容器服务,如:tomcat镜像===>run===>tomcat01容器(提供服务),通过这个镜像可以创建多个容器(最终服务运行或者项目运行在 中)
容器:container
Docker 利用容器技术,独立运行一个或者一组应用,通过镜像来创建的
启动,停止,删除等基本命令
仓库:repository
仓库用来存放镜像
分为共有仓库和私有仓库
Docker Hub(默认是国外仓库)需要配置镜像加速
Docker安装
环境查看
- uname -r
查看系统内核 - cat /etc/os-release
查看系统版本
安装
安装步骤参考文档地址:https://docs.docker.com/
- 卸载旧版本
$ sudo 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
更新yum软件索引
yum makecache fast
- 安装docker docker-ce 社区版 ee 企业版
yum install docker-ce docker-ce-cli containerd.io
- 启动docker
systemctl start docker
docker version判断启动状态
卸载
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
#docker 默认工作路径
镜像加速
阿里云-容器镜像服务-镜像中心-镜像加速器
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
https://w4gi04rq.mirror.aliyuncs.com
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://w4gi04rq.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker工作流程
run 的运行流程
Docker 是一个 c/s 结构的系统,Docker的守护进程运行在主机上,通过 Socket 从客户端访问 DockerServer 接收到 Docker-Client 的指令,就会执行
Docker比vm快的原因
- Docker 比虚拟机抽象层更少
- Docker 利用的是宿主机的内核,vm则需要Guest OS
Docker的常用命令
帮助命令
docker version
#显示docker版本信息
docker info
#显示docker的系统信息,包括镜像和容器数量
docker 命令 --help
镜像命令
查看命令
docker images
#REPOSITORY TAG IMAGE ID CREATED SIZE
#仓库 标签 镜像ID 创建时间 镜像大小
可选项
-a 显示全部镜像
-f 添加过滤器
-q 仅显示id
镜像搜索命令
docker search *
#可选项,通过star来过滤
-f
--filter STARS=3000
镜像下载命令
docker pull mysql
Using default tag: latest #不写tag,默认下载latest最新版
latest: Pulling from library/mysql
a076a628af6f: Pull complete#分层下载 docker image核心联合文件系统
f6c208f3f991: Pull complete
88a9455a9165: Pull complete
406c9b8427c6: Pull complete
Digest: sha256:0fd2898dc1c946b34dceaccc3b80d38b1049285c1dab70df7480de62265d6213 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址
docker pull mysql
docker pull docker.io/library/mysql:latest#等价
联合文件系统:
将一整个文件进行分块,已经存在的文件块就不再重复下载
镜像删除命令
docker rmi -f ID
#删除指定镜像
docker rmi -f ID1 ID2
#删除多个镜像
docker rmi -f $(docker images -aq)
#删除全部镜像
容器命令
有镜像才可以创建容器
docker pull centos
新建容器并启动
docker run [可选参数] image
#可选参数说明
--name='Name' 用来区分容器
-it 使用交互方式运行,需指定交互 shell
# docker run -it centos /bin/bash
-d 后台方式运行
-p 指定端口
-p ip:主机端口:容器端口
-p 主机端口:容器端口*
-p 容器端口 指定容器端口,主机端口随机
-P 随即指定主机和容器端口
退出容器
exit 停止并退出
ctrl+p+q 退出不停止
启动和停止容器
docker start 容器ID #启动
docker restart 容器ID #重启
docker stop 容器ID #停止当前正在运行的容器
docker kill 容器ID #强制停止
列出容器
docker ps #列出当前运行容器
-a #列出所有容器 正在运行+历史运行
-n=3 #只显示最近创建的3个容器
删除容器
docker rm 容器ID
#删除指定容器,不能删除正在运行容器 加-f强制删除
docker rm -f ID1 ID2
#删除多个容器
docker rm -f $(docker ps -aq)
docker ps -a -q|xargs docker rm
#删除全部容器
进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
docker exec
#进入容器后开启一个新的终端
#推荐使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止
docker attach
#进入容器正在执行的终端,不会启动新的进程
后台启动容器
docker run -d centos
#问题docker ps发现centos停止了
常见的坑:docker容器使用后台运行,就必须有一个前台进程,否则docker发现没有应用,会自动停止
比如:nginx 容器启动后,发现自己没有提供服务,就会立即停止
文件操作
docker cp containerID:/path /path
从容器 拷贝到外界
其他命令
docker logs 查看日志
docker logs
#显示日志
-tf 显示日志
--tail number 要显示日志的条数
docker logs -tf --tail 10 containerID
docker top 查看容器中进程的信息 相当于ps
docker top 7e0cf4052f02
UID PID PPID C STIME TTY TIME CMD
root 16499 16460 0 20:23 pts/0 00:00:00 /bin/bash
docker inspect 查看镜像元数据,WEB 应用程序
#使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
docker inspect
docker stats查看cpu状态
docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
9eb4ebb6c6a1 nginx01 0.00% 3.766MiB / 1.796GiB 0.20% 5.96kB / 8.25kB 3.32MB / 4.1kB 2
commit镜像
docker commit -m='提交描述信息' -a='作者' containerID 目标镜像名:[tag]
会生成一个新的镜像 docker images可以查看
Docker可视化
portainer
docker run -d -p 2444:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
第一次开启会加载数据非常慢 admin/adminadmin
数据卷
数据卷就可以理解为一个类似于云盘备份文件夹
目录的挂载,将容器内的目录,挂载到Linux上,实现容器的持久化和同步操作,容器间数据共享
数据卷的生命周期一直持续到没有容器使用为止
一旦持久化到本地,本地数据不会删除
管理卷
docker volume create edc-nginx-vol // 创建一个自定义容器卷
docker volume ls #查看所有容器卷
docker volume inspect 卷名 #查看指定容器卷详情信息
使用数据卷挂载
直接使用命令来挂载 -v
docker run -it -v 主机目录:docker目录
#docker inspect 容器id 查看挂在情况
# "Mounts": [
{
"Type": "bind",
"Source": "/root/test", #主机内地址
"Destination": "/home", #docker地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
创建的数据卷是双向同步,重启容器仍然生效
可以一次映射多个目录 -v -v
例:安装 MySQL
docker run -d -p 2444:3306 -v /root/test/conf:/etc/mysql/conf.d -v /root/test/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
-d 后台运行 down
-p 指定端口 port
-e 环境配置 environment
-v 卷挂载 volume
--name 容器名
连接成功
如果 mysql 容器被删除,因为是同步的,本地数据依然存在
具名挂载和匿名挂载
匿名
docker run -d -v /etc --name anouy centos
b0d9271dd4b0f271facac5a622ef1cf7e46d965d1de29e8a3792dd62e735b0be
#-v 加了一个值,代表容器内目录,没有写容器外目录
docker volume ls
DRIVER VOLUME NAME
local 3f81a21b85cc8c3f828a753552862ff0d001373802e40dd3e69e9068a6d46809
具名
docker run -d -v detailed-centos:/etc --name detailed-centos centos
#所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxx/_data
指定路径挂载
docker run -d -v /root/docker/:/etc --name detailed-centos centos
扩展
通过 -v 容器内路径:ro rw更改读写权限
ro readonly 只读
rw readwrite 可读可写
#设置权限后,容器挂载出来就有限制了
ro 容器内部无法操作,只能宿主机操作
2.dockerfile 创建镜像时挂载
dockerfile:
FROM centos
VOLUME ["volume1","volume2"]
#这种属于匿名挂载
#docker build 去构建镜像
#docker build -f ./dockerfile -t centos:dockerfile .
#最后的 . 一定要加
docker run -it 8b068d66468a
[root@cc4ba081cb71 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
# docker inspect
"Mounts": [
{
"Type": "volume",
"Name": "14efdacd4cf5f4711883e5864f6b227567d3f2bbca1919338695bd84c3565dcc",
"Source": "/var/lib/docker/volumes/14efdacd4cf5f4711883e5864f6b227567d3f2bbca1919338695bd84c3565dcc/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "84ed0b1105a9a46a0cc683bbfc661553525d75365790e0b257076c718491f4d4",
"Source": "/var/lib/docker/volumes/84ed0b1105a9a46a0cc683bbfc661553525d75365790e0b257076c718491f4d4/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
如果在构建镜像时没有挂载卷,就要手动镜像挂载 -v 卷名:容器内路径
数据卷容器
docker run --volumes-from cc4ba081cb71 -it centos
#去会继承 cc4ba081cb71 的卷,他们的卷之间是共享同步的
#如果删除 cc4ba081cb71 不影响继承的子
#此时 cc4ba081cb71 就叫数据卷容器
[root@3ad997f0779b /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
# docker inspect
"Mounts": [
{
"Type": "volume",
"Name": "14efdacd4cf5f4711883e5864f6b227567d3f2bbca1919338695bd84c3565dcc",
"Source": "/var/lib/docker/volumes/14efdacd4cf5f4711883e5864f6b227567d3f2bbca1919338695bd84c3565dcc/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "84ed0b1105a9a46a0cc683bbfc661553525d75365790e0b257076c718491f4d4",
"Source": "/var/lib/docker/volumes/84ed0b1105a9a46a0cc683bbfc661553525d75365790e0b257076c718491f4d4/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
Dockerfile
Dockerfile 就是用来构建 docker 镜像的构建文件
通过这个脚本可以生成镜像
构建步骤
- 编写 dockerfile 文件
- docker build 构建成为一个镜像
docker build -f ./dockerfile -t centos:dockerfile .
-t name:tag
最后的 . 代表本次执行的上下文路径 - docker run 运行镜像
- docker push
基础知识
- 每一个保留关键字(指令)都必须是大写字母
- 执行从上到下顺序执行
-
#
表示注释 - 每一个指令都会创建提交一个新的镜像层
指令
FROM #指定基础镜像
MAINTAINER #指定维护者,就是镜像是谁写的,姓名+邮箱
RUN #镜像构建时需要运行的命令,RUN 是在 docker build运行
ADD #具体步骤,ADD 指令和 COPY 的使用格式一致
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #保留端口位置
CMD #指定容器启动时要运行的命令,只有最后一个会生效,可以被替代,CMD 在docker run 时运行
ENTRYPOINT #指定容器启动时要运行的命令,可以追加命令
COPY #类似于ADD,将文件拷贝到镜像中
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
ONBUILD #当构建的一个被继承Dockerfile时就会运行ONBUILD指令
ENV #构建时设置环境变量
实例
最基础的镜像 scratch
dockerfile
FROM centos
MAINTAINER Ocean<22222@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
#默认工作目录是 根目录
RUN yum -y install vim
EXPOSE 80
CMD echo $MYPATH
CMD /bin/bash
docker build -f ./dockerfile -t centos:dockerfile .
docker history images-id 查看安装过程
[root@izbp1i7e0dqxcb89vkdgc3z ~]#docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos dockerfile 8b068d66468a 2 hours ago 209MB
nginx latest f6d0b4767a6c 4 days ago 133MB
mysql latest d4c3cafb11d5 4 days ago 545MB
centos latest 300e315adb2f 5 weeks ago 209MB
portainer/portainer latest 62771b0b9b09 5 months ago 79.1MB
[root@izbp1i7e0dqxcb89vkdgc3z ~]# docker history 8b068d66468a
IMAGE CREATED CREATED BY SIZE COMMENT
8b068d66468a 2 hours ago /bin/sh -c #(nop) VOLUME [volume01 volume02] 0B
300e315adb2f 5 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 5 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 5 weeks ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
CMD和ENTRYPOINT区别
CMD
dockerfile:
FROM centos
CDM ["ls","-a"]
#ls -a会被整体替换
[root@izbp1i7e0dqxcb89vkdgc3z test]# docker run 358b9081be07 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
[root@izbp1i7e0dqxcb89vkdgc3z test]# docker run 358b9081be07 ls -l
total 48
lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x 5 root root 340 Jan 17 08:07 dev
drwxr-xr-x 1 root root 4096 Jan 17 08:07 etc
drwxr-xr-x 2 root root 4096 Nov 3 15:22 home
lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 15:22 media
ENTRYPOINT
直接拼接到后边
Docker网络
每启动一个 docker 容器,docker 就会给 docker 容器分配一个 ip,我们只要安装了 docker,就会有一个网卡 docker0 桥接模式,使用的技术是 evth-pair 技术
evth-pair 技术就是一对的虚拟设备接口,成对出现,一端连着协议,一端彼此相连,充当一个桥梁,连接虚拟网络
物理机与容器可以相互ping,容器与容器可以相互ping
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:16:3e:10:ea:ad brd ff:ff:ff:ff:ff:ff
inet 172.17.28.202/18 brd 172.17.63.255 scope global dynamic eth0
valid_lft 314460373sec preferred_lft 314460373sec
#3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:33:55:ac:a4 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
valid_lft forever preferred_lft forever
docker中所有的网络接口都是虚拟的,转发效率高
只要容器删除,对应网桥就没了
–link
本质:就是在hosts配置中增加一个ip containerID
自定义网络
查看docker 网络配置 docker network ls
[root@izbp1i7e0dqxcb89vkdgc3z ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
36e3dbde727f bridge bridge local
a4be1eae4e1a host host local
bdf237354def none null local
- bridge 桥接docker默认
- none 不配置网络
- host 和宿主机共享网络
- container 容器网络联通(用的少,局限很大)
一般用docker bridge
自定义网络命令docker network create
[root@izbp1i7e0dqxcb89vkdgc3z ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
36e3dbde727f bridge bridge local
a4be1eae4e1a host host local
bdf237354def none null local
[root@izbp1i7e0dqxcb89vkdgc3z ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 myney
8504ea7a574c83fa21d6175cff5fe496b4974063533b673cdd79222669b6cbb5
# driver 网络类型
# subnet 子网划分
# gateway 网关
[root@izbp1i7e0dqxcb89vkdgc3z ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
36e3dbde727f bridge bridge local
a4be1eae4e1a host host local
8504ea7a574c myney bridge local
bdf237354def none null local
[root@izbp1i7e0dqxcb89vkdgc3z ~]# docker network inspect myney
[
{
"Name": "myney",
"Id": "8504ea7a574c83fa21d6175cff5fe496b4974063533b673cdd79222669b6cbb5",
"Created": "2021-01-19T08:49:04.652984133+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": {},
"Options": {},
"Labels": {}
}
]
容器加入自定义网络
docker run -d -P --name centos-net-01 --net mynet centos
# run启动时不加 net 参数,默认值就是 bridge
win cmd ssh报错
Bad owner or permissions on C:\Users\q2723/.ssh/config
需要把 .ssh 文件夹内文件删除
ssh user@ip
984133+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”: {},
“Options”: {},
“Labels”: {}
}
]
容器加入自定义网络
```bash
docker run -d -P --name centos-net-01 --net mynet centos
# run启动时不加 net 参数,默认值就是 bridge
win cmd ssh报错
Bad owner or permissions on C:\Users\q2723/.ssh/config
需要把 .ssh 文件夹内文件删除
ssh user@ip