docker基础详解

文章目录

    • 虚拟机和docker的区别
          • CentOS安装docker
    • 配置docker加速器
          • 镜像命令
          • 容器命令
          • 镜像原理
          • docker容器数据卷
          • docker安装mysql
          • 已经运行的容器修改端口号
          • firewalld 与 iptables的区别
          • docker中启动所有的容器命令
          • 安装Portainer
    • 查看docker占用磁盘的情况、清理垃圾

Docker是GO语言编写的,解决了运行环境和配置问题

虚拟机和docker的区别

虚拟机:虚拟一套完整的操作系统【软件+硬件】,最后在操作系统上安装应用程序

docker:不模拟完整的操作系统,更不会虚拟硬件,只将软件运行需要的资源打包到容器中,应用程序直接通过docker引擎和宿主机操作系统的内核进行交换【docker和宿主机共享一个操作系统

docker容器之间相互隔离,每个容器都有自己的文件系统,容器之间进程互不影响

DevOps:开发自运维

Docker必须在6.5版本及其以上的CentOS运行

docker的三大要素:镜像 image、容器 container、仓库

镜像就是类, 相当于一个只读的模板,容器就是对象

容器是用镜像文件创建的运行实例,一个镜像可以创建多个容器

仓库是集中存储镜像文件的地方,分为公开库和私有库,最大的公开库docker hub,存放了大量的镜像,一般国内都用阿里云、网易云

Registry:注册服务器

一个Registry上有多个Repository,一个仓库中包含了多个镜像,一个镜像可以创建多个容器,一个容器运行一种服务

每个镜像有不同的标签tag

Docker是一个管理引擎,是容器运行的载体

RHEL:Red Hat Enterprise Linux 红帽企业版linux系统
CentOS:开源版的红帽企业版linux系统
Fedora:费多拉 开源版的红帽个人版linux系统

EPEL:用于为红帽系操作系统提供软件包
EPEL的使用:安装epel-release的软件包,这个软件包会自动配置yum的软件仓库
CentOS安装docker

见官网,安装好将docker的镜像仓库设置为阿里云的

systemctl start docker   //启动docker
systemctl stop docker  //停止docker
systemctl restart docker //重启docker

docker是个client-service结构的系统, docker的守护进程daemon运行在主机上,然后通过socket从客户端连接到主机上,守护进程从客户端接收命令并管理运行在主机上的容器,注意:所有命令都要经过守护进程

配置docker加速器

vim /etc/docker/daemon.json 
--------------------------------------------------------------------------------
# 配置内容
{
	"registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
}
# 执行命令生效
systemctl daemon-reload
systemctl restart docker
镜像命令
查看dokcer版本:docker version
查询docker的完整信息:docker info
docker帮助命令:docker --help

docker images:本地镜像仓库的镜像列表
docker images -a:显示本地仓库的全部镜像(包含中间层镜像)
docker images -q:只显示镜像的唯一标示ID
docker images --digests:显示镜像列表中包含镜像的摘要信息
docker images --no-trunc:显示完整的镜像信息

镜像的仓库源          镜像的版本标签        镜像的唯一标示         镜像的创建时间       镜像的大小
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        9 months ago        1.84kB

同一仓库源有多个TAG,代表这个仓库源的不同版本,我们使用 REPOSITORY:TAG 来表示不同的镜像
如果不指定镜像的版本标签,默认版本标签为:lastest,即REPOSITORY:lastest

(1)docker search 镜像名称:到https://hub.docker.com上去查询镜像
【即使本地配置镜像仓库为阿里云,但仍然到https://hub.docker.com上去进行查询】
docker search --filter=stars=50  镜像名称:到https://hub.docker.com上去查询点赞数超过50的镜像
docker search --filter=stars=30 mysql

(2) docker pull 镜像名称[:tag]  到本地指定的镜像仓库拉取镜像,不指定tag版本号,默认使用latest版本

(3) docker rmi  镜像名称[:tag]或镜像id      删除本地镜像,不指定tag版本号,默认使用latest版本
    docker rmi -f 镜像名称[:tag] 或镜像id   强制删除本地镜像, 即使容器正在使用该容器
   其中i表示image
(4) docker rmi -f 镜像名1[:tag] 镜像名2[:tag]  删除多个本地镜像
(5) docker rmi -f $(docker -aq)        删除本机所有镜像   $()是linux命令
容器命令
  • 创建并进入运行的容器

    docker run -it 镜像名称或镜像id    作用:在docker的容器中运行指定镜像  
    其中:-i以交互模式运行,让容器的标准输入保持打开
         -t:为容器重新分配一个伪终端,并绑定到容器的标准输入上 【通常it一起使用】
         --name:为容器指定名称 如果不指定,则自动随机生成一个
         -P:随机端口映射
         -p:指定端口映射,有以下四钟格式【docker容器的端口和宿主机的映射关系】
             ip:hostPort:containerPort
             ip::containerPort
             hostPort:containerPort
             containerPort
    修改端口号映射:/var/lib/docker/containers/容器完整的id目录下的json文件中记录了端口,修改后重启
    

    在前台运行容器:docker run -it 镜像名称或镜像id --name 容器名称
    在后台运行容器:docker run -d 镜像名称或镜像id

docker后台运行,必须有一个前台进程。
容器运行的命令如果不是那些一直挂起的命令(如:top、tail),就会自动退出,因此docker执行后台运行命令后,无前台进程,执行docker -ps看不到正在运行的进程

举例:
docker run -d 0f3e07c0138f /bin/sh -c “while true;do echo 123;sleep 2;done”
-d:在后台运行,上述命令通过死循环来让容器在后台持续运行,不会因为前台无进程而自杀
0f3e07c0138f:镜像id,也可以是镜像名称
sh -c:让 bash 将一个字串作为完整的命令来执行

  • 查看容器状态

    docker logs -tf 容器id/容器名称: 查看容器的运行日志

    其中:-t:显示时间戳 -f:跟踪日志,实时显示新增日志 follow

    docker top 容器id/容器名称: 查看容器内运行的进程

    docker inspect 容器id/容器名称:查看容器内部的详细信息

    docker ps 查看docker当前正在运行的容器
    docker ps -a 查看docker正在运行的容器和历史上运行过的容器
    docker ps -l 查看docker最近创建的容器
    docker ps -n 3 查看docker最近创建的3个容器
    docker ps -q 静默模式,只显示容器编号
    docker ps --no-trunc 不截取输出正在运行的进程信息

容器有有7种状态:created(已创建)|restarting(重启中)|running(运行中)|removing(迁移中)|paused(暂停)|exited(停止)|dead

docker ps命令执行后可以看到以下信息:
CONTAINER ID     b8b43fa57cd6    容器唯一标识
IMAGE            centos          创建容器使用的镜像
COMMAND         "/bin/bash"      启动容器时运行的命令
CREATED         7 minutes ago    创建容器的时间
STATUS          Up 37 seconds    容器现在的状态
PORTS                            端口号容器的端口信息和使用的连接类型
NAMES            mycentos        容器的名称【可以自定义,也可以默认】
1.容器的两种退出方式
容器停止退出命令:exit
容器不停止退出快捷键:ctrl+p+q
从宿主机进入正在运行的容器: docker attach 容器id/容器名
使运行的容器执行指定命令而不进入容器,在容器外就可以查看结果:docker exec -it 容器id/容器名 命令行
举例:docker exec -it 6562e3d32b3a ls /home -lha

2.停止容器
docker stop 容器id/容器名称 【容器id通过docker -ps查看】

3.强制停止
docker kill 容器id/容器名称

4.启动容器
启动容器:docker start 容器id/容器名称 【容器id通过docker ps -l查看】
重启容器:docker restart 容器id/容器名称 【容器id通过docker -ps查看】

5、删除已停止的容器 
docker rm 容器id/容器名称
docker rm 容器id/容器名称
docker rm $(docker ps -aq):删除所有容器
docker rm  容器id1/容器名称1  容器id2/容器名称2:删除多个容器

6.删除运行中的容器
docker rm -f 容器id/容器名:强制删除运行中的容器

7.复制容器内的文件到宿主机
docker cp 容器id/容器名:容器内文件路径 宿主机本地目录路径

8.复制宿主机文件路径到容器内的目录下
docker cp 宿主机本地文件路径 容器id/容器名:容器内目录路径
镜像原理

UnionFS(联合文件系统):分层、轻量级的文件系统,支持对文件系统的修改作为一次提交来层层叠加

特性:一次同时加载多个文件系统,但表面看起来只是一个文件系统,实际是果果文件系统的叠加

docker镜像由一层一层的联合文件系统组成,docker镜像的最底层是bootfs(boot file system),与宿主机共用

linux系统包含bootfs和rootfs

bootfs主要包含bootloader和kernel,其中bootloader负责引导加载kernel。启动时加载bootfs,加载完成后整个kernel就在内存中了,内存使用权就交给内核,此时卸载bootfs

rootfs:在bootfs上是rootfs,包含linux系统中各种标准目录

**镜像采用分层文件系统的原因:**共享资源

多个镜像都从相同的base镜像构建而来,宿主机只需在磁盘保存一份base镜像就行了,而内存只需加载一份base镜像,其他镜像也可以共用

镜像是只读的,不能修改

  • docker commit

**docker commit的作用:**将标准的镜像文件在容器中运行起来后,自定义配置后,提交容器副本后使之成为一个自定义镜像,存放在本地镜像仓库

docker commit -m="提交的描述信息" -a="作者" 容器id 创建的新镜像的名称:[标签名]
docker容器数据卷

容器内应用程序产生的数据只能保持中容器内,通过生成镜像保持起来,否则容器删除后就不存在了,因此需要数据卷

dokcer数据卷实际是将宿主机的目录挂载到docker容器,因此如果容器有相同目录,宿主机目录会覆盖容器目录

容器数据卷的作用:(1)数据持久化 (2)不同容器之间的数据共享

  • 通过命令添加容器数据卷
docker run -it -v 宿主机目录路径A:容器内目录路径B 镜像id/镜像名   

如果需要挂载多个容器卷,则使用多个-v,其中:v是volume的简写,后面跟宿主机目录和容器内目录的映射关系
注意:【如果目录已经存在,执行时会覆盖原目录】
如果host机器上的目录不存在,docker会自动创建该目录
如果container中的目录不存在,docker会自动创建该目录
如果container中的目录已经有内容,那么docker会使用host上的目录将其

(1)添加后,在主机修改文件,容器内也会发生变化;容器进行修改,宿主机也会发生变化
(2)容器停止后,宿主机修改文件,容器重启后也会同步修改的数据
 (3) A是在主机上的地址,B是在容器中的地址,这两个地址如果不存在都会创建,一旦容器运行,AB的会完全同步。
覆盖掉

docker volume ls可以看到当前所有的volume
docker volume inspect [volume name] 获取指定volume在docker 虚拟机中的位置
docker volume create --name 容器数据卷名称   指定容器数据卷的名称,如果不指定时,创建容器时会自己生成一串很长的名称

通过docker inspect 容器id/容器名 可以查看绑定信息
"Mounts": [
            {
                "Type": "bind",    
                "Source": "/home/share",  //宿主机目录
                "Destination": "/share/data",//容器内目录
                "Mode": "",
                "RW": true,//容器对挂载容器卷目录的权限,此处为读写操作均支持
                "Propagation": "rprivate"
            }
        ]

docker run -it -v 宿主机目录:容器内目录:ro 容器id/容器名
ro:表示只读操作readonly
   "Mounts": [
            {
                "Type": "bind",
                "Source": "/home/share",
                "Destination": "/home/share",
                "Mode": "ro",
                "RW": false,   //此时为false
                "Propagation": "rprivate"
            }
        ]

  • Dockerfile添加容器卷【先创建添加了容器卷的镜像,再根据新镜像运行容器】
  1. 宿主机上编写Dockerfile,挂载数据卷到父镜像

    **Dockerfile不指定宿主机目录的原因:**dockerfile命令是创建镜像的,因此VOLUME指令只能定义容器内目录【能同时指定多个】,宿主机目录无法指定,因为宿主机有哪些目录是无法确定的

#volume test
From centos  //指定底层使用centos
VOLUME ["容器内目录1","容器内目录2"]  
CMD echo "创建成功"
CMD /bin/bash 如果没有这个命令,容器创建成功后无法直接进入容器,需要在创建命令后加/bin/bash

2.创建镜像

docker build -f dockerfile文件的路径 -t 镜像名称:[镜像版本]   dockerfile文件所在目录
其中-f:指定dockerfile文件的路径,-t  tag:表示镜像的名称和版本

如果不使用 -f,则默认将上下文路径下的名为 Dockerfile 的文件认为是构建镜像的 "Dockerfile" 
docker build -t 镜像名称:[镜像版本]  Dockerfile文件所在目录

docker build -f dockerfile文件的路径 -t 镜像名称:[镜像版本]  

3.根据镜像创建容器

docker run -it 镜像id/镜像名 /bin/bash   
如果创建挂载数据卷的镜像时没有指定命令:CMD /bin/bash 需要在创建容器的命令后面加/bin/bash

如果新添加的容器没有写权限,则只执行下面的命令添加权限:
docker run -it --privileged=true 镜像id/镜像名  /bin/bash

4.查看数据卷的默认映射关系

docker inspect 容器id/容器名称

"Mounts": [
            {
                "Type": "volume",
                "Name": "c361f213dc49570847056c2e42f61fa12e0c673ab74cafd45dba19e97c023d94",
                "Source": "/var/lib/docker/volumes/c361f213dc49570847056c2e42f61fa12e0c673ab74cafd45dba19e97c023d94/_data",   //容器目录映射的宿主机目录
                "Destination": "/home/a",  //容器目录
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "e2c560f3dfe13fd4802ee3e1e266b4a7b72ef4504cb79e4907646ef58256e5d4",
                "Source": "/var/lib/docker/volumes/e2c560f3dfe13fd4802ee3e1e266b4a7b72ef4504cb79e4907646ef58256e5d4/_data",
                "Destination": "/home/b",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }

数据卷容器:

容器A已经挂载了数据卷,其他容器通过挂载这个父容器A来实现数据共享,挂载数据卷的容器A称为数据卷容器

1.启动已经挂载了数据卷的父容器
docker run -it --name parent 镜像id/镜像名
2.挂载父容器
docker run -it --name 子容器的名称 --volumes-from 父容器的id或名称   镜像id/镜像名称  
3.在父容器或子容器挂载的数据卷中,修改后其他容器中也能看到,从而实现数据共享

**重点:**父容器被停止、删除后,不影响子容器继续使用继承的数据卷,甚至新建容器来继承子容器的数据卷

Dockerfile

Dockerfile是用来构建镜像的文件,是由一系列命令和参数构成的脚本

**镜像的构建三部曲:**编写Dockerfile→docker build→docker run

Dockerfile由四部分构成:基础镜像信息、维护者信息、镜像操作指令、容器启动时的执行指令

(1)Dockerfile中以字符开头则被视为注释

(2)保留字必须全部大写,且后面必须跟一个参数

(3)指令是从上到下顺序执行的

(4)每条指定都会创建一个新的镜像层,并对镜像进行提交

Dockerfile的执行流程:

  1. dockerfile 从基础镜像开始运行一个容器
  2. 执行一条指令并对容器做出修改后,执行类似docker commit的操作提交一个新的镜像层
  3. docker再基于新镜像运行一个新容器,然后基于新容器执行下一条指令

Dockerfile指令

FROM:指定当前要创建的镜像是基于哪个基础镜像 第一条指令必须是FROM

MAINTAINER:镜像维护者的姓名和邮箱地址

**RUN:**容器构建时需要运行的指令 【 每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像

**EXPOSE:**容器暴露的端口号

**WORKDIR:**容器运行后通过终端登录容器后,进入的第一个工作目录

**ENV:**指定环境变量 【ENV 环境变量名 指定路径】 【指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持

VOLUME:指定容器数据卷 【VOLUME [“容器内目录1”,“容器内目录2”,…]】

**ONBULID:**当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A指定基础镜像时,在build新镜像时执行父镜像的ONBUILD 指令内容


ADD和COPY的区别:

ADD:【ADD 源文件路径 目的目录路径】 将宿主机的源文件复制到容器中的指定目录,并解压文件

COPY:【COPY 源文件路径 目的目录路径】将宿主机的源文件到容器中的指定目录


CMD和ENTRYPOINT的区别:

**CMD:**指定一个容器刚启动时要运行的命令

注意:

  • 每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

  • 用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令

    【docker run -it 镜像id/镜像名 /bin/bash,其中/bin/bash就是指定的启动运行命令】

**ENTRYPOINT:**指定一个容器刚启动时要运行的命令

注意:

  • 每个Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

  • 用户启动容器时候指定了运行的命令,不会覆盖掉 CMD 指定的命令,而是在CMD指定的命令后追加参数

FROM centos
MAINTAINER liuwei
ENV mypath /root
WORKDIR $mypath
RUN yum install -y vim
RUN yum install -y net-tools
#子镜像继承此镜像时,编译自镜像时触发此命令执行
ONBUIlD RUN echo "============================================" 
ENTRYPOINT curl -s https://ip.cn

docker run -it ipcentos -i
{"ip": "47.104.5.223", "country": "山东省青岛市", "city": "阿里云"}

Base镜像(scratch):Docker hub中大部分的镜像都是基于base镜像构建的

自定义Centos

docker hub上的官方centos是不支持ifconfig和vim的

1.编写Dockerfile文件

FROM centos
MAINTAINER:liuwei

ENV mypath /root
WORKDIR $mypath

RUN yum install -y vim
Run yun install -y net-tools

CMD /bin/bash

2.构建build

docker build -t 新镜像名:版本号  Dockerfile的当前路径

3.运行run

docker run -it 镜像名:版本号

查看镜像的变更历史

docker history 镜像id/镜像名
docker安装mysql

详细安装见:https://hub.docker.com//mysql

  1. 到dockerhub查询mysql镜像,一般选择获赞数最高的镜像
docker search mysql
  1. 从远程仓库(阿里云或dockerhub)拉取获赞数最高mysql镜像到本地镜像仓库
docker pull mysql
  1. 创建容器并运行
创建运行容器之前,先将容器中/etc/mysql目录下的my.cnf文件,复制到容器外的指定目录

docker run --name db_master -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456nw --privileged=true --restart=unless-stopped \
-v /etc/localtime:/etc/localtime:ro \
-v /docker/master/conf/my.cnf:/etc/mysql/my.cnf:rw \
-v /docker/master/data:/var/lib/mysql:rw  -d 7a3923452254[镜像名或id]
----------------------------------------------------------------------
#定义存储引擎
default-storage-engine = INNODB
#定义服务器字符集和排序规则,在创建数据库和表时不特别指定字符集,这样统一采用character-set-server字符集和collation-server排序规则
character-set-server= utf8mb4
collation-server = utf8mb4_unicode_ci
#定义默认时区
default-time_zone='+8:00'【linux服务器时区必须一致】
----------------------------------------------------------------------
--restart: no         – 容器退出时,不重启容器;
           on-failure – 只有在非0状态退出时才从新启动容器;
           always     – 无论退出状态是如何,都重启容器;
-p:指定宿主机和docker的映射端口号
-v:挂载容器数据卷
-e:设置环境变量,MYSQL_ROOT_PASSWORD是mysql数据库的用户密码环境变量,这里用于指定初始密码
-d:后台运行

4.进入安装mysql的容器

docker exec -it 容器id/容器名 /bin/bash

5.docker检查容器是否运行正确

#容器ID,容器的源镜像,启动命令,创建时间,状态,端口映射信息,容器名字
docker container ls

6.从容器内连接mysql,mysql默认已经配置安装路径到环境变量

# mysql 8数据库设置远程访问和加密方式

mysql -uroot -p
show databases;
use mysql;
select user,host from user;
#设置远程连接,将host设置为%,允许所有ip访问
update user set host="%" where user="root"; 
#重新加载权限表
flush privileges;
#设置密码和密码加密方式
ALTER USER 'root'@'%' IDENTIFIED WITH caching_sha2_password BY '3927493nw';

docker服务的自启动设置

部署项目服务器时,为了应对停电等情况影响正常web项目的访问,会把Docker服务设置为开机自动启动:

systemctl enable docker.service

docker容器的自启动设置

在运行docker容器时可以加如下参数来保证每次docker服务重启后容器也自动重启:

--restart=always
   no –  容器退出时,不重启容器;
   on-failure – 只有在非0状态退出时才从新启动容器;
   always – 无论退出状态是如何,都重启容器;
   unless-stopped 如果容器正常stopped,然后机器重启或docker服务重启,这种情况下容器将不会被restart

如果已经启动了docker容器则可以使用如下命令:

docker update -–restart=always 容器id/容器名 【注意:如果要linux重启后容器自启动,则需要docker run时时不带命令,最后一个命令默认是启动命令】

还可以在使用on - failure策略时,指定Docker将尝试重新启动容器的最大次数。默认情况下,Docker将尝试永远重新启动容器。
sudo docker run -–restart=on-failure:重启最大次数  容器id/容器名

防火墙和端口

firewall-cmd内置了常用的一些服务,可以在/usr/lib/firewalld/services里面看到,如果想启用默认服务的话(以允许http服务为例):

firewall-cmd --add-service=http --permanent    //--permanent表示永久生效,不加这个参数的话只会针对本次执行完命令生效,重启后就不管用了
firewall-cmd --add-port=80/tcp --permanent  //添加端口号80
firewall-cmd --reload  //重新加载firewall配置,很关键~不然也不生效

查看开放的端口号:firewall-cmd --list-all
启动/重启/关闭/重启防火墙:systemctl  start/restart/stop/reload  firewalld
查看防火墙状态:systemctl status firewalld
已经运行的容器修改端口号
(1)停止容器与docker服务
docker stop 容器id           systemctl stop docker 
(2)修改该容器中的目录下的hostconfig.json文件
sudo vim /var/lib/docker/containers/容器hash/hostconfig.json
(3)重启docker服务和容器
firewalld 与 iptables的区别
  • firewalld 与 iptables 都是 linux 中防火墙的管理工具,实现方式不一样,但防火墙功能是由位于内核中的netfilter实现的

  • iptables 仅能通过命令行进行配置;而 firewalld 提供了图形接口

  • iptables 通过控制端口来控制服务,而 firewalld 则是通过控制协议来控制端口

  • docker中启动所有的容器命令

    docker中 启动所有的容器命令

    docker start $(docker ps -a | awk ‘{ print $1}’ | tail -n +2)

    docker中 关闭所有的容器命令

    docker stop $(docker ps -a | awk ‘{ print $1}’ | tail -n +2)

    docker中 删除所有的容器命令

    docker rm $(docker ps -a | awk ‘{ print $1}’ | tail -n +2)

    docker中 删除所有的镜像

    docker rmi $(docker images | awk ‘{print $3}’ |tail -n +2)

安装Portainer

​ 安装Docker之后,Docker守护进程会监听Unix域套接字:/var/run/docker.sock,容器中的进程可以通过套接字与Docker守护进程进行通信,而Portainer通过绑定的/var/run/docker.sock文件与Docker守护进程通信,执行各种管理操作

docker run -p 9000:9000 \
--name portainer --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /docker/portainer/data:/data \
-d portainer/portainer

查看docker占用磁盘的情况、清理垃圾

docker system df:查看docker磁盘使用情况
docker system prune:用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及dangling镜像(即无tag的镜像)

你可能感兴趣的:(docker,运维)