一.概念讲解
1.镜像的分层结构
- 共享宿主机的kerne
- base镜像提供的是最小的Linux发行版
- 同一docker主机支持运行多种Linux发行版
- 采用分层结构的最大好处是:共享资源
2. Copy-on-Write可写容器层
- 容器层以下所有镜像层都是只读的
- docker从上往下依次查找文件
- 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
- 一个镜像最多127层
3.镜像的构建
(1)docker commit 构建新镜像三部曲
- 运行容器 docker run -it --name test busybox
- 修改容器(以下命令在容器内运行) echo helloworld > testfile
- 将容器保存为新的镜像 docker commit test test:v1
(2)缺点:
- 效率低、可重复性弱、容易出错
- 使用者无法对镜像进行审计,存在安全隐患
二.搭建Docker
1.安装docker和相关依赖性
[root@server1 ~]# ls
[root@server1 ~]# cd docker/
[root@server1 docker]# ls
[root@server1 docker]# rm -rf containerd.io-1.2.5-3.1.el7.x86_64.rpm docker-ce-18.09.5-3.el7.x86_64.rpm docker-ce-18.03.1.ce-1.el7.centos.x86_64.rpm docker-ce-cli-18.09.5-3.el7.x86_64.rpm
[root@server1 docker]# ls
[root@server1 docker]# yum install * -y
2.打开docker服务
[root@server1 docker]# systemctl start docker
注意:
docker初始化后会自己刷新防火墙,所以在docker启动后就不要再重启防火墙了,因为可能后边在做端口隐射的时候有问题
3.查看docker的相关信息
[root@server1 docker]# docker info
4.当使用docker的时候,发现无法补齐,安装bash等相关安装包后,发现可以成功补齐(注意:在安装之后需要退出重新进一下)
[root@server1 docker]# docker
[root@server1 ~]# yum install -y bash-*
[root@server1 docker]# exit
[kiosk@foundation66 Desktop]$ ssh root@172.25.66.1
[root@server1 ~]# cd docker
[root@server1 docker]# docker
[root@server1 docker]# docker
三.运行一个2048小游戏
1.将事先下载好的2048镜像导入(需要将镜像导入系统内部)
[root@server1 ~]# ls
[root@server1 ~]# docker load -i game2048.tar
2.使用以下命令获取镜像,查看是否可以成功获取(如果可以查看到,就说明导入成功)
[root@server1 ~]# docker imagers
3.创建容器
#-d是打入后台,–name表示为这个容器起了一个名字为vm1
#将其打入后台,做个映射,前面的80是server这个物理机的端口。后面的80是容器的端口
[root@server1 ~]# docker run -d -p 80:80 --name vm1 game2048
4.查看容器状态
[root@server1 ~]# docker ps
5.在浏览器中输入网址,发现可以成功玩2048游戏(这个172.25.66.1是自己私有的ip地址,别人不能访问)
6.可以查看一下游戏的大小
[root@server1 ~]# du -h game2048.tar
总结:
1.容器和物理机共享内核
2.linux发行版的区别在文件系统不同
3.容器对linux内核是有要求的
4.ce是社区版本,ee是企业版本
5.使用7.5会省略很多依赖性
6.跑容器一定需要镜像,容器通过镜像生成
7.需要将镜像导入系统内部
四.搭建基础的系统镜像(ubuntu)<就是一个操作系统平台,做任何想做的事情都可以>
1.将事先下载好的ubuntu镜像导入
[root@server1 ~]# docker load -i ubuntu.tar
2.尝试是否可以成功获取ubuntu镜像
[root@server1 ~]# docker images
3.创建ubuntu容器(这里不需要将其打入后台)
#-it获取一个ddy
#名称,如vm2不能和之前的相冲突(内核相同)
[root@server1 ~]# docker run -it --name vm2 ubuntu
4.在容器ubuntu中和物理机中查看内核,发现其版本一样的,说明容器和物理机共享一个内核
root@59ba3c5e1616:/# uname -r
[kiosk@foundation66 ~]$ uname -r
5.在容器中查看ubuntu使用的ip
root@59ba3c5e1616:/# ip addr
6.在server1中查看docker的版本
[root@server1 ~]# docker version
7.在server1中查看docker宿主机的信息(发现Containers,Running,Images都变成了2)
[root@server1 ~]# docker info
8.在server1中查看docker的状态
[root@server1 ~]# docker ps
9.使用ctrl+q+p退出容器,不要使用别的,可能会卡死(只是在后台运行,就是一个进程)
10.在sercer1查看vm1和vm2的详情信息(ip分配方式是单调递增,所以在vm1上是172.17.0.2,在vm2上是172.17.0.3)
[root@server1 ~]# docker inspect vm1
[root@server1 ~]# docker inspect vm2
11.在server1中查看docker连接的物理设备(会发现,其先开始无法使用brctl命令,需要在真机中查看brctl的安装包是哪个,并在server1中下载,下载后再查看)
[root@server1 ~]# brctl show
[root@foundation66 ~]# which brctl
[root@foundation66 ~]# rpm -qf /sbin/brctl
[root@server1 ~]# yum install -y bridge-utils-1.5-9.el7.x86_64
[root@server1 ~]# brctl show
注意:
此处只要docker安装后就可以成功查看
12.做网络隔离
#查看内核路由是否开启
[root@server1 ~]# sysctl -a | grep ip_for
#查看iptables中关于docker的策略(DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80)
[root@server1 ~]# iptables -t nat -nL
总结:
1.集装箱代表标准,统一的,使用docker会减少很多交互的问题
2.docker上线会解决很多问题(如运维和开发之间的问题)
3.使用dockers的好处是,可以一次构建,就都可以使用(例如2048游戏,只需要输入一个命令,之后就都可以使用)
4.ubuntu是有外部仓库的,所以他相对linux红帽系统较简单
5.容器的优缺点,不是很安全,但是性能好
6.容器一般情况下不能更改内核,时间(因为都有联系)
7.搭建好ubuntu后会生成一个接口
8.容器之间使用docker做连接
9.docker能出去,但是进不来(除非端口映射,如pnat)
补充:
使用以下命令可以查看到安装包中脚本的内容
[root@foundation27 ~]# rpm -q --scripts httpd
五.docker的基本操作
(一)在容器中写内容(不保存)
1.连接vm2
[root@server1 ~]# docker ps
#使第一种方法,连接vm2时,会发现迟迟不出来东西,按两下回车键即可,最后,使用ctrl+q+p退出
[root@server1 ~]# docker attach vm2
#使用第二种方法连接vm2并使用ctrl+q+p退出
[root@server1 ~]# docker container attach vm2
2.连接vm2(此处不需要开启docker),在容器ubuntu中创建10个文件
[root@server1 ~]# docker attach vm2
root@59ba3c5e1616:/#
root@59ba3c5e1616:/# ls
root@59ba3c5e1616:/# touch file{1..10}
root@59ba3c5e1616:/# ls
#使用exit关闭docker
root@59ba3c5e1616:/# exit
3.退出容器后使用查看docker的进程,发现此时没有ubuntu,说明已经关闭
[root@server1 ~]# docker ps
#使用参数-a可以发现ubuntu,因为其既可以显示正在运行的容器,也可以显示关闭了的容器
[root@server1 ~]# docker ps -a
4.开启容器vm2并连接,此时发现容器内的内容没有变化
[root@server1 ~]# docker start vm2
[root@server1 ~]# docker attach vm2
root@59ba3c5e1616:/#
root@59ba3c5e1616:/# ls
root@59ba3c5e1616:/# exit
5.使用-a可以查看到docker不活跃的容器的状态,所以此时依旧可以查看到vm2,将容器vm2删除后,发现无法查看到vm2,说明将容器成功删除
[root@server1 ~]# docker ps -a
[root@server1 ~]# docker rm vm2
[root@server1 ~]# docker ps -a
6.虽然将容器删除了,可是镜像还是存在的
[root@server1 ~]# docker images
7.再次创建vm2并查看文件下的内容,发现之前新创建的10个文件此时没有
[root@server1 ~]# docker run -it --name vm2 ubuntu
root@1db077c6b881:/#
root@1db077c6b881:/# ls
8.按ctrl+q+p退出后,查看镜像,以及层
#查看所有的镜像
[root@server1 ~]# docker images
#查看ubuntu的镜像
[root@server1 ~]# docker images ubuntu
#查看ubuntu的分层结构
[root@server1 ~]# docker history ubuntu:latest
(二)在容器中写内容(保存)
1.连接容器vm2并创建文件,然后查看容器的状态
[root@server1 ~]# docker attach vm2
root@1db077c6b881:/#
root@1db077c6b881:/# ls
root@1db077c6b881:/# touch file{1..10}
root@1db077c6b881:/# ls
root@1db077c6b881:/# exit
[root@server1 ~]# docker ps
[root@server1 ~]# docker ps -a
2.在原来镜像的基础上新建一个读写层
[root@server1 ~]# docker images
-m表示说明,ubuntu:v1中的v1表示以v1的方式
[root@server1 ~]# docker commit -m "add files" vm2 ubuntu:v1
[root@server1 ~]# docker images
3.查看新建的ubuntu分层结构和之前的ubuntu间分层结构的关系
[root@server1 ~]# docker history ubuntu:v1
[root@server1 ~]# docker history ubuntu
4.删除容器vm2,再次运行新建的读写层时,发现此时内容(十个文件)没有丢失
[root@server1 ~]# docker rm vm2
[root@server1 ~]# docker run -it --name vm2 ubuntu:v1
root@c5c71f83f7db:/#
root@c5c71f83f7db:/# ls
#为了使环境干净,删除掉10个文件后并退出
root@c5c71f83f7db:/# rm -f file*
root@c5c71f83f7db:/# ls
root@c5c71f83f7db:/# exit
(三)证明docker是按照层叠加的
1.新创建一个读写层,v2表示以v2的方式运行,并查看
[root@server1 ~]# docker commit vm2 ubuntu:v2
[root@server1 ~]# docker images
2.将容器vm2删除,并运行新创建的读写层
[root@server1 ~]# docker rm vm2
[root@server1 ~]# docker run -it --name vm2 ubuntu:v2
3.按ctrl+q+p退出后,依次查看镜像和每一个读写层的分层结构,我们会发现是逐层递加的)
[root@server1 ~]# docker history ubuntu:v2
[root@server1 ~]# docker history ubuntu:v1
[root@server1 ~]# docker history ubuntu
总结:
1.attach和congtainer的区别:之前的版本没有container,但现在没区别
2.-a可以显示不管是停止的还是运行的容器
3.使用ctrl+d直接停掉容器
4.使用rm删除容器
5.以镜像为基础,构建了一个读写层,
6.只是时间到了,但是不影响
7.–name vm2 ubuntu:v2中vm2是容器名称,ubuntu:v2镜像名称,如果冒号后面不写东西,则会默认显示latest
8.v1是指以v1的方式运行
9.从上往下叠,一种视图(尽量减少镜像层数,不要层数太多,127层以内)
10.容器起来就是一个进程,消耗少
11.但是如果单纯创建一个容器,只是做访问的话,没有什么意义
12.分层的好处是共享(v2的id等信息包含了v1的,相当于只保存一份即可)
13.使用docker commit并不是特别好,因为不知道镜像是怎么构建的