docker是使用go语言写的
docker本身也是开源的
容器可以运行在任何一个linux主机中,从而可以实现虚拟化
docker ce版本
架构
1.镜像(image)2.容器(container)3.仓库(repository)
docker的依赖关系:
1.namespace命名空间编程语言中 封装--->隔离操作系统中 系统资源的隔离 例如进程,网络,文件系统等docker使用的是pid进程隔离,net网络,jpc跨进程通信访问,mnt挂载点,uts隔离内核和版本标识2.control group控制组用来分配资源 可以做资源限制 优先级的设定 资源计量 资源控制
Docker部署
1.docker部署(以debian操作系统为例)
apt-get install -y docker.io
//apt install docker-ce
docker version //查看docker版本
systemctl restart docker //重启docker服务
docker --help
2.查看docker运行状态
systemctl status docker
3.测试docker是否可以使用 看最后返回是否为hahaha 如果没找到ubuntu 会自动在仓库下一个 然后用ubuntu执行echo命令
docker run ubuntu echo "hahaha"
cat /etc/group //查看其中是否有docker
docker中安装的东西在本机的位置
/var/lib/docker/
Docker容器操作
docker images //查看当前所有的镜像docker pull ubuntu //从docker仓库拉取ubuntu的镜像docker ps //看到所有正在运行的docker容器docker ps -a //列出所有容器 不论是否正在运行docker ps -l //列出所有创建的容器docker inspect [容器名字/id] //返回容器的配置信息docker run -i -t [镜像] /bin/bash //建立一个交互式的容器docker run --name=[名字] -i -t [镜像] /bin/bash //以自己创建的名字来建立交互式的容器ctrl+p按下后松开ctrl+q //退出相应的虚拟容器docker exec -it [容器名/容器id] /bin/bash //可以进入相应创建的虚拟容器docker stop ub1 //停止相应的虚拟docker容器 发送信号等容器停止docker start ub1 //启动相应的虚拟docker容器 发送信号等容器启动docker kill [容器名/id] //立即停止容器docker rm [容器名/id] //删除容器docker rmi [镜像名] //删除镜像docker image rm [镜像名] //删除镜像PS:如果出现failed to get d-bus...这是centos7在docker上出现的bug
守护式容器--->长期运行 没有交互式会话 适合运行应用程序和会话的
docker attach [容器名/id] //转入运行中的容器docker run -d [镜像] [执行什么命令] //使用后台的方式运行容器 执行完会返回唯一的id# docker run --name ub2 -d ubuntu /bin/sh -c "while true;do echo hello haha;sleep(1);done"docker logs [参数] [容器名/id]-f 追踪日志变化 默认false-t 返回结果+时间戳--tail 结尾返回多少日志,默认falsedocker top [容器名] //查看容器中运行的进程docker exec [-d/i/t] [容器名] [参数] //在运行的容器中启动新的进程# docker exec -it ub2 /bin/bash xxx
docker部署网站
端口映射小知识
docker run -P -it ubuntu /bin/bash //把所有的端口进行映射
docker run -p 80 -it ubuntu /bin/bash //只映射80端口随机到本地的某个端口
docker run -p 80 -p 3306 -it ubuntu /bin/bash //映射两个端口
docker run -p 8080:80 -it ubuntu /bin/bash //映射80端口到外面的8080端口
docker run -p 0.0.0.0:80 -it ubuntu /bin/bash //指定ip映射
docker run -p 0.0.0.0:8080:80 -it ubuntu /bin/bash //指定ip映射
docker run -p 80 -p 443 --name web1 -it ubuntu /bin/bash
apt-get update
apt-get install nginx
apt-get install vim
apt-get install nano
ls
cd var
ls
cd www
ls
cd html
nano index.html
this is docker web1 inside<hr/><p>nihao this is used for testing </p>
whereis nginx
cd /etc/nginx/
ls
cd conf.d
vi site1.conf
server{
listen *:80;
server_name www.site1.com;
location /{
root /var/www/html;
}
}
nginx -c /etc/nginx/nginx.conf //如果出现pid问题
nginx -s reload
docker ps //查看相应开放的端口
访问192.168.109.137:[相应的随机端口]
ctrl+p+q //退出
docker -port web1 //专门查看端口
docker stop web1
重新启动的命令
docker attach web1 #进入web1容器内部
docker start web1
service nginx start //开启nginx服务
Docker的镜像和仓库
查看和删除
docker images [参数]
-a 所有
-f 过滤
-q 只显示镜像id
docker images --no-trunc //查看镜像完整的id
docker inspect ubuntu:latest //查看其镜像的信息
docker rmi ubuntu:latest //删除镜像
docker rmi [镜像id] //删除镜像
docker hub 获取和推送镜像
docker search ubuntu //查找关于ubuntu镜像的信息
docker search -s 3 ubuntu //查找3星以上的镜像
docker pull [参数] [镜像名] //拉取镜像 -a表示所有都拉
docker push [镜像名] //推送镜像
docker push 项目名/nginx //会把增量提交上去
如果要修改docker仓库
/etc/default/docker
DOCKER_OPTS="--registry-mirror=http://新的地址"
如果要完整上传到dockerhub上:
docker login
修改tag
docker tag [镜像:tag] [项目名]/[镜像:tag]
docker push ubweb1:latest selaful/debian1:ubweb1
构建镜像(就是把现存的某些容器进行打包变成镜像 之后就可以在网上公开让别人下载了)
docker commit
docker commit -a "by zj" -m "have nginx" [容器id] [新镜像名]
之后返回的id就是镜像id -a是指定的作者 -m是镜像的信息
在此构建的镜像的基础上运行新的镜像 和之前的ubuntu镜像一致 本质相同 其中ubweb1是刚才构建的新的镜像
docker run -d --name web2 -p 80 -p 443 -it ubweb1 /bin/bash
备注:
出现报错
unix://var/run/docker.sock.......is running? 的解决方法:
systemctl daemon-reload
systemctl reatart docker.service
Docker构建和备份
1.通过文件构建镜像
touch dockerfile //创建dockerfile
vi dockerfile
#First DockerfileFROM ubuntu:latestMAINTAINER dormancypress "xxx@qq.com"RUN apt-get updateRUN apt-get install -y nginxEXPOSE 80
2.开始构建容器
docker build -t [自己的镜像名:新的tag] [Dockerfile的目录]
#docker build -t [自己的镜像名:新的tag] [Dockerfile的目录] -no--cache //不使用缓存的方式构建容器
#docker build -t ubuntu:ubweb2 /root/
3.查看容器构建结果
docker images
dockerfile指令(解释docker构建镜像中的内容的意义)
FROM [镜像名/标签名] #指定镜像名
MAINTAINER [标签] #给镜像一个注释
RUN [命令] #当前镜像会运行什么命令 RUN apt-get update && apt-get install -y nginx
EXPOSE [端口] #镜像使用什么端口
CMD #在容器运行的时候执行什么命令
ENTRYPOINT ["命令"] #不会被docker的命令覆盖 可以使用docker run --entrypoint覆盖
ADD #有类似tar打包的功能
COPY #复制文件 把
#COPY [xxx.html自己的文件] [/var/www/html/index.html虚拟机的文件]
#COPY /root/test.html /var/www/html/index.html 把自己当前dockerfile所在文件的目录的test.html
#COPY f1/* /var/www/html/ 把自己当前dockerfile所在文件的目录的f1文件夹中所有内容复制到虚拟机的目录下
VOLUME ["/data"]卷
WORKDIR #在容器内部设置工作目录
#WORKDIR /path/to/workdir 用绝对路径
ENV [key]=[value] 环境变量
USER XX #镜像使用什么用户来运行 默认情况是root用户
#USER uid:gid
ONBUILD #镜像触发器 当自己的镜像被其他镜像作为基础镜像执行的时候 插入指令
dockerfile构建过程
1.从基础镜像运行一个容器
2.执行指令对容器做出的修改
3.执行类似的commit的操作 提交新的镜像层
4.基于新的镜像层运行容器
5.执行Dockerfile下一条指令
docker把镜像保存在本地和本地恢复
docker images //可以查看相应的镜像名和TAG,id等信息
#docker save -o ubweb1.tar selafu1/debian1:ubweb1
docker save -o [文件名.tar] [镜像名:tag] #把镜像保存为当前文件夹下的tar文件
docker load --input [文件名.tar] #恢复tar文件为images
容器的网络连接
实验环境:
1.创建两个docker容器 分别搭建nginx的网站服务 注意两个docker容器最好使用同一个镜像进行搭建
2.分别在各自的界面的index.html中展示不同的内容以进行区分
3.在两个容器内部分别进行以下命令的执行
apt-get install -y net-tools #安装网络工具
apt-get install -y inetutils-ping #安装ping工具
在web1中进行ifconfig结果:
在web2中进行ifconfig的结果:
通过ping实验可以发现 两台docker容器之间可以互相ping通 同时也都可以ping通公网的百度 说明网络是通畅的
(1)默认情况下web1可以ping通web2 因为docker使用虚拟网桥进行连接
(2)但是每次重启的话ip会变
所以可以使用如下命令
docker kill web1
docker rm web1
docker run -d --name web1 --link=web2:w2 -p 80 -p 443 -it web1:latest /bin/bash
此时由于web1是基于web2而构建出来的派生容器 其别名叫w2 所以可以直接ping别名 这样也不用担心每次登录进去以后IP地址会发生改变
接下来借助curl在容器内对另一个容器的网页进行访问来测试
1.首先 两个容器都分别安装一下curl
apt-get install -y curl
2.接下来首先查看docker ps -a 查看相应的访问端口
web1上是内网80端口映射到外网的49164 内网地址是172.17.0.2
web2上是内网80端口映射到外网的49160 内网地址是172.17.0.3
首先通过curl测试web1和web2内部之间访问可不可以直接访问80端口
curl w2:80
w2本质上是修改了环境变量和host文件
拒绝访问:
适用于对于docker的隔离安全性要求比较高的时候 避免黑客入侵了web1 从而内网访问入侵web2
/etc/default/dockerDOCKER_OPTS="--icc=false"
之后重启docker服务 那么容器之间就无法相互访问了
允许特定的容器访问:
DOCKER_OPTS="--icc=false --iptables=true"iptables -L -n可以看到防火墙DROP了的数据iptables -F清空之后重启docker服务即可
容器和外部网络的连接
sysctl net.ipv4.conf.all.forwarding如果结果是1就说明可以转发iptables -l DOCKER -s [源地址] -d [docker的地址] -p TCP --dport 80 -j DROP
Docker数据管理
1.docker容器数据卷(本质就是本机和虚拟机之间的数据共享和即时互通)(最好在容器中创建容器进行测试 直接虚拟机测试可能因为系统权限等问题失败)
在容器启动的时候初始化
对数据卷修改是即时进行的
docker run -v ~/[本地目录]:/[容器目录] -it ubuntu:latest /bin/bash //如果目录不存在就创建docker run -v ~/[本地目录]:/[容器目录]:ro -it ubuntu:latest /bin/bash //使用read only只读权限
举例子:
docker run -v ~/root:/benji --name temp_docker -it ubuntu:latest /bin/bash
ls
进入这个虚拟机以后 在ls后可以看到目录中出现了一个benji的文件夹
cd benji/
ls
mkdir haha
2.如果使用dockerfile
FROM ubuntu:latest
VOLUME ["/[本地目录]","/[容器目录]"]
CMD /bin/bash
2.docker数据卷容器
docker run --volumes-from [数据卷容器名] #挂载数据卷容器
#docker run -it --name test1 --volumes-from [目标容器名] ubuntu:latest /bin/bash
#这样数据卷之间就是共享的 不过不安全
3.数据卷备份
docker run --volumes-from [备份的容器名] -v [本地位置]:[容器位置]:wr --name [名字] ubuntu:latest tar cvf /容器中的位置/backup.tar [/容器中需要备份的目录]
备份举例:
docker run --volumes-from web1 -v ~/backup:/backup --name web1backup ubuntu:latest tar cvf /backup/test1.tar /datavolume1
4.数据库备份的还原操作
docker run --volumes-from [备份的容器名] -v [本地位置]:[容器位置]:wr --name [名字] ubuntu:latest tar xvf /容器中的位置/backup.tar [/容器中需要备份的目录]
Docker端口映射修改
举例:例如需要修改web1容器的端口映射情况
docker ps -a
docker kill web1
之后在执行docker容器的虚拟机中找到如下目录
/var/lib/docker/containers/
根据刚才docker ps -a获得的相应web1容器的开头信息找到相应的文件夹
找到hostconfig.json
修改相应的端口映射信息
ps:由于web1是基于web2关联的 所以需要开启web1需要先开启web2
systemctl restart docker
docker ps -a
docker start web2
docker start web1