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 psdocker 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端口进行访问,或者直接替代为别名

image

访问控制

拒绝访问

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
posted @ 2022-09-17 15:27  icui4cu  阅读(158)  评论(0编辑  收藏  举报