zoukankan      html  css  js  c++  java
  • Docker

    一:容器简介

    1.简介

    容器是一种轻量级、可移植、并将应用程序进行的打包的技术,使应用程序可以在几乎任何地方以相同的方式运行

    • Docker将镜像文件运行起来后,产生的对象就是容器
    • 容器相当于是镜像运行起来的一个实例
    • 容器具备一定的生命周期
    • 可以借助docker ps命令查看运行的容器,如同在linux上利用ps命令查看运行着的进程那样

    2.容器 与 虚拟机

    • 容器和虚拟机一样,都会对物理硬件资源进行共享使用
    • 容器和虚拟机的生命周期比较相似(创建、运行、暂停、关闭等等)
    • 容器中或虚拟机中都可以安装各种应用,如redis、mysql、nginx等。也就是说,在容器中的操作,如同在一个虚拟机(操作系统)中操作一样
    • 同虚拟机一样,容器创建后,会存储在宿主机上:linux上位于/var/lib/docker/containers

    容器并不是虚拟机,但它们有很多相似的地方

    • 虚拟机的创建、启动和关闭都是基于一个完整的操作系统。一个虚拟机就是一个完整的操作系统
    • 而容器直接运行在宿主机的内核上,其本质上以一系列进程的结合
    • 容器是轻量级的,虚拟机是重量级的。首先容器不需要额外的资源来管理(不需要Hypervisor、Guest OS),虚拟机额外更多的性能消耗;其次创建、启动或关闭容器,如同创建、启动或者关闭进程那么轻松,而创建、启动、关闭一个操作系统就没那么方便了
    • 也因此,意味着在给定的硬件上能运行更多数量的容器,甚至可以直接把Docker运行在虚拟机上

    3.生命周期

    虚拟机的生命周期

    Docker的生命周期

    二:容器生命周期管理

    0.查看容器列表

    选项 释义
    -a 列出当前正在运行的容器+之前运行过的容器
    -n=? 显示最近创建的容器
    -q 只显示容器的编号
    docker ps		# 查看所有正在运行的容器
    docker ps -a	# 查看所有正在运行的容器(包括之前运行过的)
    

    1.创建与启动容器

    在 Docker 中,真正对外提供服务的还是容器

    在Docker容器中,至少有1个应用程序运行在前台

    语法

    # 创建容器
    docker create [选项] [镜像ID]|[镜像名称] [命令]
    
    # 启动容器
    docker start [选项] [镜像ID]|[镜像名称] [命令]
    
    # 创建并启动容器
    docker run [选项] [镜像ID]|[镜像名称] [命令]
    
    # 这里的 [命令] 是镜像内部默认的命令:Cmd中的,可以用inspect查看
    
    docker run		相当于 docker create + docker start –a		# 前台模式
    docker run -d	相当于 docker create + docker start		# 后台模式
    

    选项

    选项 释义
    -d 以守护进程方式运行
    -e 设置容器中的环境变量
    -h 指定容器内的主机名
    -i 保持标准输出打开
    -p 指定映射端口 [宿主主机端口号:容器内部端口号]
    -P 随机映射端口
    -t 分配一个伪终端
    -v 挂载目录(数据卷)到容器
    (使用docker commit时,挂载目录无法保存到镜像)
    --rm 当容器生命周期结束时,自动删除该容器
    --link 链接到另一个容器
    --name 为启动的容器设置一个名字(也将名称解析到Docker DNS中)
    --network 指定使用哪个网络(bridge、host、none、container)

    实例

    docker run -d --name nginx -p 80:80 nginx
    
    
    # 会运行在前台(不推荐)
    docker run nginx:1.19.5
    
    # 以守护进程的方式启动
    docker run -d nginx:1.19.5
    
    # 指定启动的名称(也将名称加入到Docker DNS中)
    docker run -d --name nginx_bak nginx:1.19.5
    
    
    # 容器生命周期结束后自动删除
    docker run -d --rm nginx:1.19.5
    
    # 查看
    iptables -vnL
    
    # 启动 并 进入容器
    docker run -it centos /bin/bash
    
    # 挂载
    docker run -d --rm -v /root/django:/data /python:3.6.8
    
    # 设置环境变量
    docker run --name mysql_server -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.32
    

    特点

    1.检查本地是否有所需镜像(如果没有,就立即去相应的镜像仓库下载)
    2.根据参数启动

    2.暂停 与 取消暂停容器

    容器可以被暂停,也可以恢复运行

    # 暂停1个容器
    docker pause [容器ID|容器名称]
    
    
    # 恢复运行1个容器
    docker unpause [容器ID|容器名称]
    

    3.停止容器

    docker 终止容器是首先向容器发送 SIGTERM 信号,等待一段时间超时后(默认 10 秒)

    再发送 SIGKILL 信号 来终止容器

    实例

    # 关闭所有容器
    docker stop $(docker ps -qa)	# 停止所有的容器
    
    
    # 先启动nginx
    [root@localhost ~]# docker run -d --name nginx -p 80:80 nginx
    87d4a352b7543be1aa5abaeafafbd2c7dbda236505b3159d975de1f158e04e23
    
    
    # 查看已启动的容器
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                NAMES
    87d4a352b754        nginx               "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp   nginx
    
    
    # 关闭该容器
    [root@localhost ~]# docker stop nginx
    nginx
    
    
    # 再次查看已启动的容器
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    
    
    # 此时,可以直接用start再次启动该容器
    [root@localhost ~]# docker start nginx
    nginx
    
    
    # 再一次查看已启动的容器(这里可以看到,启动的时间是第1次启动的时间,并不是再次启动的时间)
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
    87d4a352b754        nginx               "/docker-entrypoint.…"   3 minutes ago       Up 16 seconds       0.0.0.0:80->80/tcp   nginx
    

    4.终止容器

    强制并立即关闭一个或多个处于暂停状态或者运行状态的容器

    选项 释义
    -s,--signal string 指定发送给容器的关闭信号 (默认“KILL”信号)
    docker kill [选项] [容器ID|容器名称]
    

    docker stop和docker kill的区别

    # 一 前提知识点:
        1 Linux其中两种终止进程的信号是:SIGTERM和SIGKILL
        2 SIGKILL信号:无条件终止进程信号。
        进程接收到该信号会立即终止,不进行清理和暂存工作。
        该信号不能被忽略、处理和阻塞,它向系统管理员提供了可以杀死任何进程的方法。
        3  SIGTERM信号:程序终结信号,可以由kill命令产生。
        与SIGKILL不同的是,SIGTERM信号可以被阻塞和终止,以便程序在退出前可以保存工作或清理临时文件等。
    
    # 二 docker stop 会先发出SIGTERM信号给进程,告诉进程即将会被关闭。在-t指定的等待时间过了之后,将会立即发出SIGKILL信号,直接关闭容器。
    # 三 docker kill 直接发出SIGKILL信号关闭容器。但也可以通过-s参数修改发出的信号。
    
    # 四 因此会发现在docker stop的等过过程中,如果终止docker stop的执行,容器最终没有被关闭。而docker kill几乎是立刻发生,无法撤销。
    
    # 五 此外还有些异常原因也会导致容器被关闭,比如docker daemon重启、容器内部进程运行发生错误等等“异常原因”。
    

    5.重启容器

    重启一个或多个处于运行状态、暂停状态、关闭状态或者新建状态的容器
    该命令相当于stop和start命令的结合

    选项 释义
    -f 强行删除容器(会使用 SIGKILL信号)
    -v 同时删除绑定在容器上的数据卷
    docker rm [选项] [容器ID|容器名称]
    

    6.进入容器

    在使用容器的过程中,难免需要进入容器进行排查问题

    下面介绍一下进入容器的几种方式

    1.attach

    通过管道连接容器内的PID为1的进程

    attach 是最早 docker 官方推出的进入容器的命令了,不过使用该命令有一个问题

    当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示

    如果有一个窗口阻塞了,那么其他窗口也无法再进行操作,当所有窗口退出时,容器结束

    docker attach nginx
    
    缺点:
    • 没有提供可执行命令的地方
    • attach结束时,容器也跟着结束了(终止的是在前台运行的进程)

    2.exec

    既 attach 之后,exec 是官方推出的有一个新的进入容器的命令

    这个命令相当于在容器中执行一个命令

    在宿主主机上 通过exec的方式 在容器内执行某个命令(在外部执行内部的命令)

    选项 释义
    -i 打开标准输出
    -t 创建1个伪终端
    docker exec -it [容器ID]
    
    # 实例
    docker exec 容器名称 bash
    
    # 退出容器
    exit
    
    # 每天5点定时清理日志
    00 05 * * * docker exec 容器名 > /eoor/django.log
    

    3.nsenter

    (这是Linux中的命令)创建1个管道,连接容器

    需要配合 docker inspect 来使用(早期没有 exec 命令时,企业当中最长用的方式之一)

    Docker 是用 golang 语言开发,所以它也支持 go 语言的摸版语法

    nsenter --target $( docker inspect -f {{.State.Pid}}
    nginxv1 ) --mount --uts --ipc --net --pid
    

    4.ssh

    在生产环境中排除了使用 docker attach 命令进入容器之后,相信大家第一个想到的就是 ssh

    在镜像(或容器) 中安装 SSH Server,这样就能保证多人进入容器且相互之间不受干扰了,相信大家在当前的生产环境中(没有 使用 Docker 的情况)也是这样做的

    但是使用了 Docker 容器之后不建议使用 ssh 进入到 Docker 容器内

    5.总结

    进入 docker container 中一般情况下有 4 种方式,最常用的是 exec nsenter 这2种

    Nsenter 和 exec 之间的区别?

    • Exec 是 docker 自带的命令,Nsenter 是 Linux 提供的命令
    • Exec 相当于在容器内执行一个命令,而 Nsenter 是仅仅进入容器之中而已

    7.退出容器

    # 容器停止并退出
    exit
    
    
    # 容器不停止 退出
    Ctrl + P + Q
    

    8.删除容器

    普通删除

    可以使用 docker rm 命令来删除处于终止或退出状态的容器

    语法

    docker rm 容器名
    

    强制删除

    强制删除一个正在运行的容器

    docker rm 容器名	# 删除指定的容器(不能删除正在运行的容器)
    docker rm -f 容器名	# 强制删除指定的容器
    docker rm -f $(docker ps -qa)	# 删除所有的容器
    docker ps -qa | xargs dicker rm	# 删除所有的容器(使用管道符)
    

    实例

    # 删除所有已停止的容器
    docker rm $(docker ps -a -q)
    
    
    # 删除所有容器(慎用)
    docker rm -f $(docker ps -a -q)
    

    三:其他常用命令

    查看容器详情信息

    用于查看本地一个或多个容器的详细信息

    选项 释义
    -f 利用特定Go语言的format格式输出结果
    -s 显示总大小
    # 语法
    docker inspect [选项] [容器ID]
    
    # 实例
    [root@localhost ~]# docker inspect 7537a7662db9
    [
        {
            "Id": "7537a7662db9e42a2a881fc239245e632b885173dfd3eca36fdca91f46e7f657",
            "Created": "2020-12-01T10:23:41.90270839Z",
            "Path": "/docker-entrypoint.sh",
            "Args": [
            ....
    

    后台启动容器

    # 命令 docker run -d 镜像名
    [root@localhost ~]# docker run -d centos
    6ab985f8e3b0bf5384389d291e3bdb94175a285204a6b054f541a59eeb2eaff9
    
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    
    # 问题:docker ps之后,发现centos容器停止了
    

    常见的坑:

    docker 容器使用后台运行,就必须要有1个前台进程

    如果docker发现没有前台进程,就会自动停止

    查看日志

    选项 释义
    -tf 显示日志
    --tail 要显示的日志条数
    # 语法
    docker logs -f -t --tail 10 容器ID
    
    
    # 编写一段shell脚本
    [root@localhost ~]# docker run -d centos /bin/sh -c "while true; do echo Darker; sleep 1; done"
    e665be69f9129b3e962309f091a5e87af363254e270f4ab223379f70dde7da92
    
    # 查看正在运行的容器
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    e665be69f912        centos              "/bin/sh -c 'while t…"   12 seconds ago      Up 11 seconds                           angry_turing
    
    
    # 查看容器的日志
    [root@localhost ~]# docker logs -tf --tail 10 e665be69f912
    2020-12-01T08:09:57.431354440Z Darker
    2020-12-01T08:09:58.435476619Z Darker
    2020-12-01T08:09:59.440251520Z Darker
    2020-12-01T08:10:00.442683974Z Darker
    2020-12-01T08:10:01.448639433Z Darker
    2020-12-01T08:10:02.453106883Z Darker
    2020-12-01T08:10:03.457659408Z Darker
    2020-12-01T08:10:04.461011131Z Darker
    2020-12-01T08:10:05.464084959Z Darker
    

    查看容器中的进程信息

    # 语法
    docker top 容器ID
    
    # 实例
    [root@localhost ~]# docker top 7537a7662db9
    UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
    root                4855                4838                0                   18:23               ?                   00:00:00            nginx: master process nginx -g daemon off;
    101                 4905                4855                0                   18:23               ?                   00:00:00            nginx: worker process
    

    容器重命名

    # 语法
    docker rename [容器ID] 容器的新名称
    
    # 实例
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
    7537a7662db9        nginx               "/docker-entrypoint.…"   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp   awesome_ride
    [root@localhost ~]# docker rename 7537a7662db9 my_nginx
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
    7537a7662db9        nginx               "/docker-entrypoint.…"   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp   my_nginx
    

    从容器内拷贝文件到主机上

    # 语法
    docker cp [容器ID]:[容器内路径] [宿主主机路径]
    docker cp [宿主主机路径] [容器ID]:[容器内路径] 
    
    # 查看当前主机目录
    [root@localhost ~]# ls
    anaconda-ks.cfg
    
    
    # 启动 并 进入容器
    [root@localhost ~]# docker run -it centos /bin/bash
    
    
    # 查看容器内的目录(当前是在根目录)
    [root@9575f94d0a03 /]# ls
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    
    
    # 在容器内创建1个文件
    [root@9575f94d0a03 /]# touch darker.txt
    
    
    # 退出该容器
    [root@9575f94d0a03 /]# exit
    exit
    
    
    # 查看所有容器(为了找到刚才的容器ID)
    [root@localhost ~]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
    9575f94d0a03        centos              "/bin/bash"              3 minutes ago       Exited (0) 17 seconds ago                       wonderful_driscoll
    e015ce3ec587        centos              "/bin/bash"              5 minutes ago       Exited (0) 5 minutes ago                        naughty_chaplygin
    
    
    # 将刚刚在容器中创建的文件拷贝到主机上
    [root@localhost ~]# docker cp 9575f94d0a03:/darker.txt /home
    

    四:总结

    练习

    1.安装并启动mysql

    # 拉取镜像
    [root@localhost ~]# docker pull mysql:5.7.32
    
    # 运行,并设置root密码
    [root@localhost ~]# docker run --name mysql_server -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.32
    
    # 查看已启动容器
    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
    9ce38e811c19        mysql:5.7.32        "docker-entrypoint.s…"   9 seconds ago       Up 8 seconds        0.0.0.0:3306->3306/tcp, 33060/tcp   mysql_server
    
    # 进入该容器,进行操作(此时,localhost ~ 会变成该容器的id)
    [root@localhost ~]# docker exec -it mysql_server bash
    root@9ce38e811c19:/# mysql -u root -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 5
    Server version: 5.7.32 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql>
    
    
    # 此时,也可以通过Navicat等工具,远程连接该MySQL
    ssh通道连接服务器的,MySQL账号密码用该MySQL容器的
    

    2.安装并启动nginx,并打开指定网页

    # 先创建1个目录,用于挂载
    mkdir /test
    
    # 在该目录下创建一个index.html
    vim /test/index.html
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>Hello World</h1>
    
    </body>
    </html>
    
    # 运行nginx,端口映射 80:80 将宿主机的/test/挂载到/usr/share/nginx/html中
    docker run -d -it --name nginx_service -v /test/:/usr/share/nginx/html -p 80:80 nginx
    
    
    # 访问
    curl 127.0.0.1:80/index.html
    
  • 相关阅读:
    离开页面时提示用户
    返回顶部
    【转】 MySQL主从(Master-Slave)复制
    判断是否到达指定时间,可以精确到秒
    【转】tomcat优化-有改protocol 和 缓存 集群方案
    【转】Spring+Websocket实现消息的推送
    【转】SpringMVC整合websocket实现消息推送及触发
    【转】java即时消息推送
    大型网站对图片的下载,存放,及压缩管理
    简单的linux压力测试工具webbench
  • 原文地址:https://www.cnblogs.com/xuexianqi/p/14157074.html
Copyright © 2011-2022 走看看