21.docker
docker安装
docker介绍
1.docker是一个开源的容器应用,go语言编写,可以自己进行修改,可以把应用打包成轻量级的东西移植到容器中,而且docker可以运行在任何Linux主机实现虚拟化
2.kvm实现的虚拟化是把整机虚拟化,而docker可以将一个服务(apache)放到一个容器中进行虚拟化
3.docker有很多应用场景,在企业中进行批量部署,可以将web应用批量打包发布到很多服务器上,也可以进行自动化检测等
4.docker可以真正在硬件上实现性能最大化使用
docker架构
镜像(image):相当于文件系统,如Ubuntu、apache
容器(container):镜像运行的位置
仓库(repository):保存镜像的地方
docker依赖
1.namespace(命名空间):在编程语言中称为的封装,达到隔离的效果;在操作系统中叫做系统资源隔离,如进程、网络、文件系统
docker使用的是pid进程隔离,net网络,ipc(跨进程通信访问),mnt挂载点,uts隔离内核和版本标识
2.control group(控制组):用来分配资源,做资源限制,优先级设定,资源计量,资源控制(允许在什么时候使用多少资源)
docker部署
Linux版本:Debian 4.19.132-1 (2020-07-24) x86_64 GNU/Linux
更新后安装docker
apt-get update
apt-get install -y docker.io # 社区维护版
查看docker安装版本和运行情况
docker version
systemctl status docker
自动下载Ubuntu并输出echo命令测试docker是否正常
docker run ubuntu echo "hahahaha"
cat /etc/group
可以发现有docker组,之前自动下载的Ubuntu在var/lib/docker/containers
,存储的镜像在var/lib/docker/image
docker重启、帮助和可使用IO状态
systecmctl restart docker
docker --help
docker stats
docker的容器操作
如果出现failed to get d-bus、connection等字样,为CentOS7在docker上的一个bug,建议换成CentOS6/8或者不用CentOS系统
容器的普通操作
查看docker当前容器
docker images
启动或删除容器
docker pull ubuntu # 从docker仓库拉去Ubuntu镜像
建立交互式容器
docker run -i -t [镜像] /bin/bash # -t tty终端 -i image/镜像
查看所有正在运行的容器
docker ps
列出所有的容器
docker ps -a
列出所有创建的容器
docker ps -l
返回容器配置信息
docker inspect [镜像名/镜像id]
以自定义名字来运行镜像
docker run --name=[名字] -i -t [镜像ID/镜像名] /bin/bash
按下Ctrl+p后再按Ctrl+q退出;
docker exec -it [名字] /bin/bash
重新进入
进入挂起的容器
docker exec -it [镜像名/镜像id] /bin/bash
发送信号给容器,让容器开启/停止运行(关机)
docker start/stop [容器名/容器id]
直接停止容器(拔电源)
docker kill [容器名]
删除容器
dock rm [容器名/容器id]
需要先停止(stop)容器才能删除
守护式容器
长期运行,无交互式会话,适合运行应用程序和会话
转入运行中的容器
docker attach [容器名/容器id]
exec和attach区别:exec退出容器终端不会导致容器停止,attach退出容器终端会导致容器停止;多个窗口attach到同一个容器所有命令会同步,一个窗口阻塞其他窗口也无法执行操作
使用后台的方式运行容器
docker run -d [镜像] [执行的命令]
docker run --name ubuntu-2 ubuntu /bin/sh -c "while true;do echo hello;sleep 1;done"
返回唯一容器的ID,通过attach进入,Ctrl+C退出,start重启
查看镜像日志
docker logs [参数] [容器名/容器ID]
-f # 追踪日志变化,默认false
-t # 返回结果+时间戳
查看容器中运行的进程
docker top [容器名/容器ID]
在运行的容器中启动新的进程
docker exec [-d/i/t] [容器名/容器id] [参数]
docker exec -it ubuntu-2 /bin/bash -c "while true;do echo nihao;sleep 1;done"
退出新进程后重新进入依然执行旧进程
docker部署web
端口映射
把所有的端口进行映射(docker的80端口会变成本地的80端口)
docker run -P -it ubuntu /bin/bash
只映射docker的80端口到本地
docker run -p 80 -it ubuntu /bin/bash
映射docker的80和3306两个端口到本地
docker run -p 80 -p 3306 -it ubuntu /bin/bash
把docker的80端口映射到本地的8080端口(本地在外docker在内)
docker run -p 8080:80 -it ubuntu /bin/bash
指定IP映射到80端口(默认全局映射)
docker run -p 0.0.0.0:80 -it ubuntu /bin/bash
主机上不一定只有一个IP,有些IP不想做网站,可以选择映射到主机不同的IP
指定主机上IP的8080端口映射到容器的80端口
docker run -p 0.0.0.0:8080:80 -it ubuntu /bin/bash
部署web服务器
在Ubuntu容器80、443端口映射到主机,取名web1
docker run -p 80 -p 443 --name web1 -it ubuntu /bin/bash
安装nginx等相关依赖
apt-get update
apt-get install nginx
apt-get install nano
apt-get install vim
编辑并启动nginx有关
# 出现网站目录
cd /var/www/html
vi index.html
# 查找nginx安装位置
whereis nginx
cd /etc/nginx/conf.d
# 编辑配置文件
vi site1.com
server{
listen *:80;
server_name www.site1.com;
location /{
root /var/www/html;
}
}
# 加载nginx
nginx -c /etc/nginx/nginx.conf
nginx -s reload
ctrl+p+q
退出docker后docker ps
或docker port web1
专门查看容器运行情况,发现重新随机映射本地端口到80,通过访问随机端口进行访问;每次重启docker还要进去使用nginx service start
启动nginx
docker镜像部署
镜像和仓库
查看镜像(简略id)
docker images [参数]
-a 所有
-f 过滤
-q 只显示镜像id
查看镜像完整id:
docker images --no-trunc
查看镜像的完整信息
docker inspect ubuntu:lastest
删除镜像
docker rmi ubuntu:latest
docker rmi [镜像名/镜像id]
获取和推送镜像(docker hub)
https://registry.hub.docker.com
查找关于Ubuntu镜像的信息
docker search ubuntu
# 查找3星以上的ubuntu镜像
docker search -s 3 ubuntu
拉取镜像
docker pull [参数] [镜像名]
-a 拉取所有
关于没有守护进程的报错
**报错:**unix://var/run/docker.sock…… is running?
**解决**
systemctl daemon-reload
systemctl restart docker.service
构建镜像
打包镜像
docker commit -a "by xxx" -m "Have nginx" [简短镜像id] [新镜像名]
-a 指定作者
-m 镜像信息(备注)
利用该镜像新构建一个容器
docker run -d --name [容器名] -p 80 -p 443 -it [打包的新镜像名] /bin/bash
推送镜像
docker push [镜像名]
# 如果修改docker仓库,如公司添加私有的仓库
vi /etc/default/docker
DOCKER_OPTS="--registry-mirror=https://新的地址"
# 完整上传到dockerhub上
docker login # 输入账号密码
docker tag [本地要上传的镜像名:tag内容] [仓库中自建的项目名/仓库名:tag内容]
docker tag ubweb1:latest test/debian1:ubweb1
# 上传镜像到仓库
docker push [仓库项目名/仓库名:tag内容]
docker push test/debian1:ubweb1
通过文件构建镜像
dockerfile构建和备份镜像
创建dockerfile
touch /root/dockerfile
vi dockerfile
# First Dockerfile
FROM ubuntu:latest
MAINTAINER dormancypress "xxx@qq.com" # 联系方式
# 建立镜像的运行东西
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80
根据dockerfile内容构建容器
docker build -t [自定义的镜像名:新的tag] [Dockerfile的目录]
docker build -t ubuntu_test:ubweb2 /root/
# 不使用缓存
docker build -t [自定义的镜像名:新的tag] [Dockerfile的目录] --no-cache
把镜像保存在本地(针对不推送云上仓库,保存在本地硬盘/移动硬盘)
docker save -o [保存文件名] [镜像名:tag内容]
docker save -o ubweb1.tar ubweb1_test:ubweb1
恢复本地tar镜像文件为images
docker load --input [文件名.tar]
docker load --input ubweb1.tar
dockerfile指令
FROM [镜像名/标签名] # 指定镜像名
MAINTAINER [标签] # 给镜像一个注释
RUN [命令] # 让指定镜像运行什么命令
eg:RUN apt-get update && apt-get install -y nginx
EXPOSE [端口] # 镜像使用什么端口
CMD # 在容器运行时执行什么命令
ENTRYPOINT ["命令"] # 不会被docker命令覆盖,可以使用docker run --entrypoint命令覆盖
ADD # 类似tar的打包功能
COPY # 复制文件
eg:COPY f1/* /var/ww/html/ # 把dockerfile所在文件目录的f1文件夹中所有文件复制到容器的/var/www/html目录中
VOLUME ["/data'] # 卷
WORKDIR # 在容器内部设置工作目录,用绝对路径
eg:WORKDIR /path/to/workdir
ENV [key]=[value] # 设置环境变量
USER xxx/USER uid:gid # 镜像使用什么用户来运行,默认root用户
ONBUILD # 镜像触发器,当一个镜像被其他镜像作为基础镜像执行的时候,插入命令.如ubuntu+nginx生成的新镜像是以ubuntu作为基础镜像,该命令就可以在ubuntu上使用
dockerfile构建过程
1.从基础镜像运行一个容器
2.执行对容器做出的修改的指令
3.执行类似的commit(压缩成新的镜像并提交)的操作,提交新的镜像层
4.基于新的镜像层运行容器
5.执行dockerfile下一条指令
容器的网络连接
网络互联
分别进入不同的含有web服务的容器
docker attach web1
docker attach web2
apt-get install -y net-tools # 安装网络工具
apt-get install -y inetutils-ping # 安装ping工具
默认情况下web1可以ping通web2,因为docker使用虚拟网桥进行连接,单每次重启ip会变
通过设置另一台主机别名使得不用通过IP进行ping
docker run -d --name [镜像名] --link=[镜像名/tag] -p 80 -it [镜像名/tag] /bin/bash
docker run -d --name web1 --link=web2:w2 -p 80 -p 443 -it selaful/debian:ubweb1 /bin/bash
# 安装网络工具+ping工具
此时只要ping w2或者curl w2,这里w2代表一切web2的ip地址,实际上修改了web1的环境变量和host文件,w2直接解析到web2
web1对外映射32775端口,web2对外映射32777端口,但是彼此在同一个内网中,可以通过curl各自的内网IP和80端口进行访问,或者直接替代为别名
访问控制
拒绝访问
vi /etc/default/docker
修改:DOCKER_OPTS="--icc=false"
重启docker服务,那么容器之间无法互相访问
允许特定的容器访问
vi /etc/default/docker
修改:DOCKER_OPTS="--icc=false --iptables=true" # 允许iptables进行访问
前往本机
iptables -L -n # 查看iptables规则情况,可以看到防火墙DROP了数据
iptables -F # 清空iptables规则设置
service docker restart # 重新启用docker的服务,此时iptables设置中docker的规则链在第一位
容器和外部网络的连接(不允许容器访问外部网络)
sysctl net.ipv4.conf.all.forwarding # 如果是1就可以转发
iptables -l DOCKER -s [源地址] -d [docker的服务器地址] -p TCP --deport 80 -j DROP # iptables禁止访问外部
docker的数据管理
docker容器数据卷
在容器启动的时候初始化,对数据卷的修改是即时进行的
将本机硬盘映射到容器,该目录下容器和本机的创建和修改操作都会互通
# 如果目录不存在就创建
docker run -v ~/[本地目录]:/[容器目录] -it ubuntu:latest /bin/bash
docker run -v /root:/benji -it ubuntu:latest /bin/bash
# 使用只读权限,映射到容器中,容器只读
docker run -v ~/[本地目录]:/[容器目录]:ro -it ubuntu:latest /bin/bash
使用dockerfile进行卷管理
FROM ubuntu:latest
VOLUME ["/[本地目录]","/[容器目录"]
CMD /bin/bash
使用数据卷容器
# 挂载指定数据卷容器,进行共享
docker run --volumes-from [数据卷容器名]
# 创建一个以ubuntu镜像的test1容器,指定volumes为共享容器
docker run -it --name test1 --volumes-from [目标容器名] ubuntu:latest
数据卷备份
docker run --volumes-from [备份的容器名] -v [容器文件位置]:[本地位置]:wr ubuntu tar cvf /容器中的位置/backup.tar [/容器中需要备份的目录]
docker run --volumes-from web1 -v ~/backup:/backup --name web1backup ubuntu:latest tar cvf /backup/test1.tar /datavolume1
# 将web1容器的backup目录挂载到主机的backup目录下,有写入权限,容器ID为Ubuntu;同时压缩容器中的/datavolume1目录到主机的/backup目录下取名test1.tar
# 可以把挂载理解为两个文件目录共享,即容器的backup目录主机的backup目录也能看到并能修改
数据卷的还原
docker run -it --volumes-from nginxback -v /root/test:/backup nginx tar xvf /backup/web.tar
# 将备份的容器nginxback从主机/root/test挂载到容器的backup目录下,容器ID为nginx,解压容器/backup下的web.tar文件,由于挂载,可以理解为主机/root/test目录和容器/backup目录是共享的
docker修改端口映射
对原来docker run -p 80 -p 443 --name web1 -it ubuntu /bin/bash
随机映射的80和443端口不满意,重新修改端口映射
docker stop web1
打开配置文件:/var/lib/docker/containers/容器hash值/hostconfig.json
修改PortBindings中端口的HostPort值为想映射的端口即可
"PortBindings":{"443/tcp":[{"HostIp":"","HostPort":"映射的端口"}]
systemctl restart docker
docker start web1
本文来自博客园,作者:icui4cu,转载请注明原文链接:https://www.cnblogs.com/icui4cu/p/16702724.html