• HCIE-容器docker


    1、Docker容器技术

    Docker类似集装箱的概念,容器是一个运行时环境,软件带环境一起安装。通过Docker镜像 ( images ) 将应用程序所需要的系统环境,由下而上打包,达到应用程序跨平台间的运行。Docker是一家公司的名字,产品叫 Docker(GO语言开发),是一种容器技术,除了 docker,还有podman,lxd/lxc,containerd,runc等容器技术。kubernetes(k和s之间8个字母简称k8s)k8s 容器编排工具。
    虚拟机属于虚拟化技术,Docker容器技术也是虚拟化技术,属于轻量级的虚拟化。虚拟机虽然可以隔离出很多“子电脑”,但占用空间更大,启动更慢,虚拟机软件可能还要花钱(例如VMWare)。而容器技术它不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境(类似“集装箱”)。它启动时间很快,几秒钟就能完成,它对资源的利用率很高(一台主机可以同时运行几千个Docker容器)。它占的空间很小,虚拟机一般要几GB到几十GB的空间,而容器只需要MB级甚至KB级。
    虚拟机(virtual machine)是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在Windows 系统里面运行Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。虚拟机的缺点:1、资源占用多;2、冗余步骤多;3 、启动慢。
    容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
    在这里插入图片描述
    在这里插入图片描述
    为什么Docker比较 VM 快?
    1、docker有着比虚拟机更少的抽象层。由于docker不需要Hypervisor虚拟化软件层实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
    2、docker利用的是宿主机的内核,而不需要Guest OS(虚拟机操作系统)。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。因而避免引寻、加载操作系统内核整个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,整个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了整个过程,因此新建一个docker容器只需要几秒钟。
    Docker 和传统虚拟化方式的不同之处:
    1、传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
    2、容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟化,因此容器要比传统虚拟机更为轻便。
    3、每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
    虚拟机和容器的区别:虚拟机目的是为了隔离用户;容器目的是为了隔离应用进程(namespace cgroup)。
    在这里插入图片描述
    linux模板制作:
    1、安装配置操作系统,使用CentOS stream 8镜像
    之前:RHEL 8.4 发布了,CentOS紧随其后,发布CentOS 8.4
    之后:CentOS 走在前面,成为RHEL上游,再去发布RHEL
    使用minimal最小化安装Stream-8,最小化安装用# ip a查看ip

    linux模板制作配置要求,cpu至少2个,建议vcpus4个、内存4G、硬盘100G,网卡使用NAT模式。
    1.编辑网卡
    [root@temp network-scripts]# vi ifcfg-ens160
    [root@temp network-scripts]# cat ifcfg-ens160
    TYPE=Ethernet
    BOOTPROTO=dhcp
    NAME=ens160
    DEVICE=ens160
    ONBOOT=yes
    
    2.清除密钥文件
    [root@temp ~]# cd /etc/ssh/
    [root@temp ssh]# ls
    moduli      ssh_config.d  ssh_host_ecdsa_key      ssh_host_ed25519_key      ssh_host_rsa_key
    ssh_config  sshd_config   ssh_host_ecdsa_key.pub  ssh_host_ed25519_key.pub  ssh_host_rsa_key.pub
    [root@temp ssh]# rm -rf ssh_host_*
    [root@temp ssh]# ls
    moduli  ssh_config  ssh_config.d  sshd_config
    
    3.清除machine-id
    清除,不是删除
    [root@temp ssh]# cat /etc/machine-id 
    5f9da25a629841b8bdba92d307182c0d
    [root@temp ssh]# cat /dev/null > /etc/machine-id 
    [root@temp ssh]# cat /etc/machine-id 
    
    4.关机
    init 0
    
    5.完整克隆(以后用到的虚拟机,都可以进行完整克隆)
    
    6.手工配置静态ip
    [root@temp network-scripts]# cat ifcfg-ens160
    TYPE=Ethernet
    BOOTPROTO=none
    NAME=ens160
    DEVICE=ens160
    ONBOOT=yes
    IPADDR=192.168.100.177
    NETMASK=255.255.255.0
    GATEWAY=192.168.100.2
    DNS1=192.168.100.2
    [root@temp network-scripts]# nmcli conn down ens160
    [root@temp network-scripts]# nmcli conn up ens160
    
    7.修改主机名
    [root@temp network-scripts]# hostnamectl set-hostname docker
    [root@temp network-scripts]# exit
    logout
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    2、安装docker(Docker官网:http://www.docker.com,官网文档: https://docs.docker.com/get-docker/)

    镜像(Image)就是一个只读的模板,一个镜像可以创建很多容器,镜像是一个不包含liunx内核的精简的操作系统。容器(Container)是用镜像创建的运行实例,每个容器都是相互隔离的。
    仓库(Repository)是集中存放镜像文件的场所。仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
    仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub(https://hub.docker.com/,docker工具默认从这个地址下载镜像),存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云等,国内比国外网络快。可以把镜像发布到仓库中,需要的时候从仓库中拉下来就可以了。
    在这里插入图片描述

    1、安装基础软件包,用自带的yum在线源(/etc/yum.repos.d),安装bash-completion软件包能用tab键补全命令
    yum install -y vim net-tools bash-completion yum-utils
    2、下载docker-ce.repo文件
    [root@docker yum.repos.d]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    [root@docker yum.repos.d]# ls  查看会多个docker-ce.repo
    3、安装docker
    查看docker版本,yum list docker-ce --showduplicates | sort -r
    默认安装最新版,yum install -y docker-ce
    安装指定版本,yum install -y docker-ce-20.10.22 docker-ce-cli-20.10.22
    查看已安装的docker版本,# docker -v
    Docker version 24.0.6, build ed223bc
    4、开启docker服务
    [root@docker ~]# systemctl status docker.service 
    [root@docker ~]# systemctl start docker.service 
    [root@docker ~]# systemctl enable docker.service
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3、镜像操作

    求帮助,docker --help
    搜索镜像,docker search 某个镜像的名称如mysql    对应DockerHub仓库中的镜像
    下载镜像,拉取镜像后面如果没有带版本,那么默认是latest,docker pull centos
    默认从Docker Hub(https://hub.docker.com/)下载镜像比较慢,国内比国外网络快、配置镜像加速器。
    指定版本下载镜像,docker pull mysql:5.7
    查询镜像,docker images
    查询显示所有镜像id,docker images -qa
    删除镜像,用镜像id首位或镜像名删除都行,docker rmi centos
    强制删除镜像,docker rmi -f 镜像id
    删除多个镜像,docker rmi -f 镜像名:tag 镜像名:tag
    删除全部镜像,docker rmi -f $(docker images -qa)
    修改镜像名称,会复制一个镜像并重命名,docker tag mysql:latest mysql:v918
    查看镜像历史信息,docker history centos
    查看镜像详细信息, docker image inspect nginx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    镜像仓库
    推送镜像,因为是往自己的仓库里面推送的,所以推送之前必须要登录仓库和tag修改镜像名称。不管你的仓库是公开的,还是私有的,只要是push推送都要登录仓库。如果仓库是公开的,拉取pull,所有人都可以拉取;如果仓库是私有的,拉取pull,只能自己拉取使用。

    推送镜像,阿里云
    先创建个人实例,再创建命名空间(一个账号最多3个命名空间),最后手工创建镜像仓库(可以获取登录、拉取、上传的命令)
    
    1、登入仓库,docker login --username=clisdodo@126.com registry.cn-hangzhou.aliyuncs.com
    2、改镜像名称,docker tag centos:latest registry.cn-hangzhou.aliyuncs.com/cloudcs/centos:v917
    [root@docker ~]# docker images 修改镜像名称,会复制一个镜像并重命名
    3、推送镜像到仓库,docker push registry.cn-hangzhou.aliyuncs.com/cloudcs/centos:v917
    镜像标准的完整名称
    服务器                             仓库/分类  镜像  版本
    registry.cn-hangzhou.aliyuncs.com/cloudcs/centos:latest
    从指定仓库下载镜像,docker pull registry.cn-hangzhou.aliyuncs.com/cloudcs/mysql:888
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    推送镜像,华为云,登录华为云生成临时登录链接
    没有命名空间,改成了组织,一个账号默认最多创建5个组织
    
    [root@docker ~]# docker login -u cn-north-4@xxxxxxx -p xxxxxx swr.cn-north-4.myhuaweicloud.com
    [root@docker ~]# docker tag busybox:latest swr.cn-north-4.myhuaweicloud.com/cloudcs/busybox:v917
    [root@docker ~]# docker push swr.cn-north-4.myhuaweicloud.com/cloudcs/busybox:v917
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用Harbor构建企业级私有镜像仓库,参考 https://blog.51cto.com/cloudcs/6051557

    https://github.com/goharbor/harbor/releases
    关闭防火墙及SELinux
    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
    sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
    echo '192.168.100.177 docker' >> /etc/hosts
    tar -zxvf harbor-offline-installer-v2.6.2.tgz 
    cd harbor/      
    cp harbor.yml.tmpl harbor.yml
    vim harbor.yml
    #修改主机名为本机IP地址
    hostname: 192.168.100.130
    #修改端口号为5000,可自定义
    # http related config
    http:
      # port for http, default is 80. If https enabled, this port will redirect to https port
      port: 5000
    #注释 https
    # https related config
    # https:
      # https port for harbor, default is 443
      # port: 443
      # The path of cert and key files for nginx
      # certificate: /your/certificate/path
      # private_key: /your/private/key/path
    
    # # Uncomment following will enable tls communication between all harbor components
    # internal_tls:
    #   # set enabled to true means internal tls is enabled
    #   enabled: true
    #   # put your cert and key files on dir
    #   dir: /etc/harbor/tls/internal
    
    # Uncomment external_url if you want to enable external proxy
    # And when it enabled the hostname will no longer used
    # external_url: https://reg.mydomain.com:8433
    
    # The initial password of Harbor admin
    # It only works in first time to install harbor
    # Remember Change the admin password from UI after launching Harbor.
    
    #修改管理员密码
    harbor_admin_password: redhat12345
    
    在docker.service 中添加一个参数,vim /usr/lib/systemd/system/docker.service
    #在ExecStart最后添加 --insecure-registry=192.168.100.177:5000
    ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=192.168.100.177:5000
    #配置加速器(可选)
    # vim /etc/docker/daemon.json
    # cat /etc/docker/daemon.json 
    {
      "registry-mirrors": ["https://cc2d8woc.mirror.aliyuncs.com"]
    }
    重启服务
    systemctl daemon-reload 
    systemctl restart docker
    运行 prepare 脚本准备镜像
    [root@docker harbor]# ls
    common.sh  harbor.v2.7.1.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare
    [root@docker harbor]# ./prepare 
    [root@docker harbor]# ls
    common  common.sh  docker-compose.yml  harbor.v2.7.1.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare
    [root@docker harbor]# docker images
    REPOSITORY         TAG        IMAGE ID       CREATED         SIZE
    goharbor/prepare   v2.7.1     d9e019294af2   4 weeks ago     164MB
    centos             8.4.2105   5d0da3dc9764   18 months ago   231MB
    centos             latest     5d0da3dc9764   18 months ago   231MB
    vim common.sh 
    修改119行 $(docker compose version)
    #原 119 行 elif [[ $(docker-compose --version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]
    #修改为 elif [[ $(docker compose version) =~ (([0-9]+)\.([0-9]+)([\.0-9]*)) ]]
    vim install.sh 
    修改26行 DOCKER_COMPOSE="docker compose"
    #原 26 行 DOCKER_COMPOSE=docker-compose
    #修改为 DOCKER_COMPOSE="docker compose"
    安装 harbor,[root@docker harbor]# ./install.sh 
    通过命令行登录,# docker login 192.168.100.177:5000
    输入账号密码
    Authenticating with existing credentials...
    WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/engine/reference/commandline/login/#credentials-store
    Login Succeeded
    之后在浏览器中输入 192.168.100.177:5000 进行harbor访问。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    镜像保存与导入,保存镜像到本地:docker save centos:latest -o all.tar,(-o :输出到的文件)从本地导入镜像:docker load -i all.tar(-i:指定导入的文件)

    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
    busybox      latest    a416a98b71e2   2 months ago   4.26MB
    centos       latest    5d0da3dc9764   2 years ago    231MB
    [root@docker ~]# docker save busybox:latest centos:latest -o all.tar   保存镜像到本地文件
    [root@docker ~]# docker save 镜像id -o a.tar 保存镜像到本地用镜像id代替镜像名(相同镜像的镜像名可用标签区分)
    镜像重定向 > 进行保存,docker save centos > /tmp/a.tar
    [root@docker ~]# ls
    all.tar  anaconda-ks.cfg
    [root@docker ~]# docker rmi busybox:latest 
    [root@docker ~]# docker rmi centos:latest 
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
    [root@docker ~]# docker load -i all.tar   从本地导入镜像(-i:指定导入的文件)
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
    busybox      latest    a416a98b71e2   2 months ago   4.26MB
    centos       latest    5d0da3dc9764   2 years ago    231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    镜像加速器,配置阿里云。默认情况下,下载镜像是从Docker Hub(https://hub.docker.com/)上拉取的,国外网站网络会有点卡,这时候可以选择代理(加速器),国内比国外网络快。
    在这里插入图片描述

    [root@docker ~]# vim /etc/docker/daemon.json
    [root@docker ~]# cat /etc/docker/daemon.json 
    {
      "registry-mirrors": ["https://dddddd.mirror.aliyuncs.com"]
    }
    [root@docker ~]# systemctl daemon-reload         daemon-reload: 重新加载某个服务的配置文件
    [root@docker ~]# systemctl restart docker
    现在下载镜像就很快了,[root@docker ~]# docker pull mysql
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    镜像加速器,配置华为云,和阿里云操作一致。
    在这里插入图片描述

    4、容器操作

    查询正在运行的容器,docker ps
    查询所有的容器(运行的/非运行的),docker ps -a
    运行一个容器run,利用centos镜像运行容器,docker run centos
    [root@docker ~]# docker ps -a
    CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS                     PORTS     NAMES
    6b965c5a9486   centos    "/bin/bash"   5 seconds ago   Exited (0) 3 seconds ago            distracted_proskuriakova
    正常情况下容器的status应该是run,原因是因为容器默认运行的进程是/bin/bash,因为bash shell 它是一瞬间完成的。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    删除一个容器rm,-f强制删除,docker rm -f 容器ID(只写容器ID首位就行)
    删除所有容器,docker rm -f $(docker ps -qa)
    [root@docker ~]# docker ps -q  查询正在运行的容器id
    [root@docker ~]# docker ps -qa  查询所有容器id(运行的/非运行的)
    
    为容器的shell添加一个伪终端-t,[root@docker ~]# docker run -t centos
    [root@c4ce30080051 /]# ls
    添加终端之后直接进入到容器里面,但是执行命令的时候卡住了,原因是虽然有了终端来承载shell命令,但是不存在交互。
    为容器添加交互-i,[root@docker ~]#  docker run -t -i centos
    [root@ee0f71706575 /]# ls
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    但是,一旦退出该容器,容器就会关闭,如果下次使用,需要提前把容器start
    为容器添加持续运行--restart always,[root@docker ~]# docker run -t -i --restart always centos
    [root@5aa5e29cd42b /]# exit
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
    5aa5e29cd42b   centos    "/bin/bash"   12 seconds ago   Up 7 seconds             elegant_hugle
    添加了--restart always参数后持续运行,一旦退出容器,容器会再次重启,容器会持续运行的。
    
    如果没有带--restart always参数持续运行容器,而且使用的attach命令进入容器,那么退出的时候,有两种选择:
    要么直接exit退出,这时候容器关闭;要么使用暂停 ctrl + p+q 进行退出,容器不会关闭。
    通过attach进入,然后exit退出后,容器会自动关闭。通过exec则不会。
    [root@docker ~]# docker run -tid --name os2 centos    运行容器时不加--restart always持续运行
    [root@docker ~]# docker exec -ti os2 /bin/bash  
    [root@e83989d30998 /]# exit   exec 退出不会关闭容器
    [root@docker ~]# docker attach os2    attach 退出会关闭容器
    [root@e83989d30998 /]# exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    当创建容器的时候,默认会直接进入到容器里面,有时仅想把容器创建出来,而不直接登录。
    为容器添加后端分离-d,[root@docker ~]# docker run -t -i -d --restart always centos
    6ce63da32b22cfaa5d37fa3858c1b3476f27a24582822dd455501c37b507e17c
    容器创建好之后,名字都是随机生成的,可以自定义容器名称。
    为容器自定义名字--name,[root@docker ~]# docker run -t -i -d --name os1 --restart always centos
    d98a402f2deddbace28ba19288702ff7a29a6a57a95136039bcfa0e489ed7a2c
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
    d98a402f2ded   centos    "/bin/bash"   5 seconds ago    Up 4 seconds              os1
    也可以进行参数简写,[root@docker ~]# docker run -tid --name os1 --restart always centos
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如何进入容器,推荐使用exec,docker exec -ti os1 /bin/bash
    1.attach这个命令只能用于默认进程为 /bin/bash 或 /bin/sh
    2.exec命令可以用于所有的进程
    3.k8s对pod的进入操作都是exec

    1[root@docker ~]# docker attach os1
    [root@d98a402f2ded /]# ls
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    [root@d98a402f2ded /]# exit
    2[root@docker ~]# docker exec -ti os1 /bin/bash
    [root@d98a402f2ded /]# ls
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    [root@d98a402f2ded /]# exit
    
    举例:比如nginx
    [root@docker ~]# docker pull nginx
    [root@docker ~]# docker history nginx:latest
    IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
    605c77e624dd   21 months ago   /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B
    发现nginx默认运行的进程不是/bin/bash 或 /bin/sh
    比如创建一个nginx容器,[root@docker ~]# docker run -tid --name web --restart always nginx
    e095a5b2852cf49a3af1ac0ac83c3838f1ed3dffd24db000642b7c93c95c0e82
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
    e095a5b2852c   nginx     "/docker-entrypoint.…"   7 seconds ago    Up 3 seconds    80/tcp    web
    通过exec可以进入,[root@docker ~]# docker exec -ti web /bin/bash
    root@e095a5b2852c:/# exit
    但是通过attach无法进入,原因是因为nginx默认运行的进程不是/bin/bash 或/bin/sh
    [root@docker ~]# docker attach web
    2023/09/19 06:11:14 [notice] 34#34: signal 28 (SIGWINCH) received
    2023/09/19 06:11:14 [notice] 33#33: signal 28 (SIGWINCH) received
    2023/09/19 06:11:14 [notice] 31#31: signal 28 (SIGWINCH) received
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    创建一个临时容器(用完即删)--rm,[root@docker ~]# docker run -ti --rm centos
    [root@aae612a0b558 /]# ls
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    [root@aae612a0b558 /]# exit
    用完退出容器后会自动删除该容器,就没必要带上-d参数了,也没必要带上--restart always持续运行。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    指定容器运行生命周期sleep(秒),[root@docker ~]# docker run -tid --name os2 centos sleep 10
    24a18821bc6ab964619d5646d483377447dc57baf6bbc38e33718277f98f5a97
    手工指定容器运行生命周期,意味着不用--restart always参数持续运行容器了。
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
    24a18821bc6a   centos    "sleep 10"               7 seconds ago    Up 6 seconds              os2
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    容器启动关闭重启start/stop/restart
    [root@docker ~]# docker stop os1
    os1
    [root@docker ~]# docker start os1
    os1
    [root@docker ~]# docker restart os1
    os1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    指定容器环境变量 -e,如果要创建一些需要传入参数的容器,比如创建mysql容器

    指定容器环境变量-e,[root@docker ~]# docker run -tid --restart always --name os1 -e a=1 centos
    850905d4164b001a39b7192b5d3079afb00508ce48a6071fe3f73e7e15266166
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@850905d4164b /]# echo $a
    1
    指定多个环境变量要用多个-e,一个-e只能指定一个环境变量。
    [root@docker ~]# docker run -tid --name d1 -e name1=heh1 -e name2=hehe2 --restart always centos
    
    举例:比如创建一个mysql容器
    [root@docker ~]# docker run -tid --name db --restart always mysql
    2de0cf9b29ff84f57115d3a08d6c78ae26296672c1bf532ddd86090166237bbe
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                       PORTS     NAMES
    2de0cf9b29ff   mysql     "docker-entrypoint.s…"   10 seconds ago   Restarting (1) 1 second ago             db
    这里状态不正常,可以去查询下该容器的日志,docker logs -tf --tail 10 db
    -t 显示时间戳,-f 动态打印最新的日志,--tail 数字 显示多少条记录。
    容器日志查询logs,[root@docker ~]# docker logs db
    2023-09-19 06:38:18+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.27-1debian10 started.
    2023-09-19 06:38:18+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
    2023-09-19 06:38:18+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.27-1debian10 started.
    2023-09-19 06:38:18+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
        You need to specify one of the following:
        - MYSQL_ROOT_PASSWORD
        - MYSQL_ALLOW_EMPTY_PASSWORD
        - MYSQL_RANDOM_ROOT_PASSWORD
    通过日志查询,发现错误信息。知道了创建mysql的时候必须要带上设置root密码的参数。
    删除db容器后再创建[root@docker ~]# docker rm -f db
    [root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat mysql
    b0365d36832c8b969cee20feb01a41f27fe7f5d3dee71532c980725ea5a752d2
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                 NAMES
    b0365d36832c   mysql     "docker-entrypoint.s…"   10 seconds ago   Up 9 seconds    3306/tcp, 33060/tcp   db
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    查看容器中运行的进程信息,docker top 容器id
    查询容器的详细信息inspect,[root@docker ~]# docker inspect db |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.3",
                        "IPAddress": "172.17.0.3",
    尝试登录mysql,[root@docker ~]# mysql
    bash: mysql: command not found
    现在没有mysql客户端,直接安装mariadb就可以了。
    [root@docker ~]# yum install -y mariadb
    [root@docker ~]# mysql -uroot -predhat -h 172.17.0.3
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 8.0.27 MySQL Community Server - GPL
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.003 sec)
    MySQL [(none)]> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    注意:当centos为7版本的时候,默认拉取的mysql最新镜像版本为 810版本。这时候是无法直接在linux里面登录的,因为密码策略问题会导致失败。如果是centos 8 /centos Stream 不会存在这个问题。

    如果centos是7版本,比如7.9.那么按照上面的流程是无法直接登录的。
    [root@thr ~]# mysql -uroot -predhat -h 172.17.0.3
    ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be
    loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared
    object file: No such file or directory
    
    [root@thr ~]# docker exec -ti os1 /bin/bash
    bash-4.4# mysql -uroot -predhat
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 9
    Server version: 8.1.0 MySQL Community Server - GPL
    Copyright (c) 2000, 2023, Oracle and/or its affiliates.
    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> show databases;
    +--------------------+
    | Database |
    +--------------------+
    | information_schema |
    | mysql |
    | performance_schema |
    | sys |
    +--------------------+
    4 rows in set (0.00 sec)
    mysql> use mysql;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    Database changed
    mysql> show tables;
    mysql> desc user;
    mysql> select user,host,plugin from user;
    +------------------+-----------+-----------------------+
    | user | host | plugin |
    +------------------+-----------+-----------------------+
    | root | % | caching_sha2_password |
    | mysql.infoschema | localhost | caching_sha2_password |
    | mysql.session | localhost | caching_sha2_password |
    | mysql.sys | localhost | caching_sha2_password |
    | root | localhost | caching_sha2_password |
    +------------------+-----------+-----------------------+
    mysql> alter user 'root'@'%' identified with mysql_native_password by 'redhat';
    Query OK, 0 rows affected (0.00 sec)
    mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'redhat';
    Query OK, 0 rows affected (0.01 sec)
    mysql> select host,user,plugin from user;
    +-----------+------------------+-----------------------+
    | host | user | plugin |
    +-----------+------------------+-----------------------+
    | % | root | mysql_native_password |
    | localhost | mysql.infoschema | caching_sha2_password |
    | localhost | mysql.session | caching_sha2_password |
    | localhost | mysql.sys | caching_sha2_password |
    | localhost | root | mysql_native_password |
    +-----------+------------------+-----------------------+
    5 rows in set (0.00 sec)
    [root@thr ~]# mysql -uroot -predhat -h 172.17.0.3
    Welcome to the MariaDB monitor. Commands end with ; or \g.
    Your MySQL connection id is 10 
    Server version: 8.1.0 MySQL Community Server - GPL 
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. 
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 
    MySQL [(none)]> show databases; 
    +--------------------+ 
    | Database | 
    +--------------------+ 
    | information_schema | 
    | mysql | 
    | performance_schema | 
    | sys | 
    +--------------------+ 
    4 rows in set (0.00 sec)
    MySQL [(none)]>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    为容器进行端口映射-p,比如创建一个nginx容器,如何在宿主机上进行访问呢?(nginx和http默认端口都是80)
    在这里插入图片描述

    -p 前面宿主机端口,后面容器端口
    [root@docker ~]# docker run -tid --name web --restart always -p 5000:80 nginx
    1aa2b86303342ad5868e016aba73fa55502475b2be295c2f83ca818c13ad321b
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS           PORTS                                   NAMES
    1aa2b8630334   nginx     "/docker-entrypoint.…"   11 seconds ago   Up 9 seconds     0.0.0.0:5000->80/tcp, :::5000->80/tcp   web
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    容器和主机之间文件的拷贝docker cp

    主机拷贝文件到容器,docker cp /etc/hosts web1:/tmp/
    [root@docker ~]# docker run -tid --name web1 --restart always nginx
    59e77d1c4229f57b48c20038f1d195289159b065ab6753c716d6203681cf98d4
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS          PORTS                                   NAMES
    59e77d1c4229   nginx     "/docker-entrypoint.…"   6 seconds ago   Up 5 seconds    80/tcp                                  web1
    1aa2b8630334   nginx     "/docker-entrypoint.…"   7 minutes ago   Up 7 minutes    0.0.0.0:5000->80/tcp, :::5000->80/tcp   web
    [root@docker ~]# cat /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    [root@docker ~]# docker cp /etc/hosts web1:/tmp/
    Successfully copied 2.05kB to web1:/tmp/
    [root@docker ~]# docker exec -ti web1 /bin/bash
    root@59e77d1c4229:/# ls /tmp/
    hosts
    
    容器拷贝文件到主机,docker cp web1:/tmp/a.txt /root/
    root@59e77d1c4229:/# cd /tmp
    root@59e77d1c4229:/tmp# touch a.txt
    root@59e77d1c4229:/tmp# ls
    a.txt  hosts
    root@59e77d1c4229:/tmp# exit
    exit
    [root@docker ~]# docker cp web1:/tmp/a.txt /root/
    Successfully copied 1.54kB to /root/
    [root@docker ~]# ls
    anaconda-ks.cfg  a.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    容器常用命令

    docker search 搜索镜像
    docker pull 拉取镜像
    docker run 运行容器
    docker attach/exec 进入容器
    docker logs 查看容器日志
    docker inspect 查看容器底层详细信息(查看IP)
    docker history 查看镜像历史信息(对外暴露端口号,进程等等)
    docker start 启动容器
    docker stop 关闭容器
    docker restart 重启容器
    docker rm 删除容器
    docker rmi 删除镜像
    docker ps 查看正在运行的容器
    docker ps -a 查看所有容器
    docker port 查看容器映射端口
    docker cp 容器和主机之间进行文件拷贝
    docker push 推送镜像
    docker tag 对镜像进行设置别名(标签)
    docker --help  求帮助
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5、容器网络

    了解Docker0 桥接

    当安装docker之后,在宿主机上(Linux)会多出一块虚拟网桥docker0(虚拟网卡/虚拟交换机/虚拟网桥)
    [root@docker ~]# ifconfig
    docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
            inet6 fe80::42:41ff:fe39:80cd  prefixlen 64  scopeid 0x20<link>
            ether 02:42:41:39:80:cd  txqueuelen 0  (Ethernet)
            RX packets 27  bytes 3642 (3.5 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 42  bytes 4225 (4.1 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
            
    通过查看得知,docker network一共有3种网络,重点关注bridge网络(桥接)。
    bridge是docker默认的网络类型,连接在相同bridge上的容器及宿主机可以相互通信;相反,连接在不同bridge的容器不能直接通信。
    host网络类型中,容器共享宿主机的网络及接口,这意味着容器的网络配置和宿主机是一样的。
    none网络类型中,容器中仅有loopback接口,无法与外界进行通信。
    [root@docker ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    5d9d6632dac4   bridge    bridge    local
    d91318448989   host      host      local
    8a522a475a44   none      null      local
    
    当创建一个容器的时候,容器默认使用的是bridge网络,对应的是docker0,该容器默认是可以连通外网的。
    [root@docker ~]#  docker run -tid --name os1 --restart always centos
    2fb0348d746f057d1f2bc2a2390795c4770a6fd1bac2ae49c459016de17c077d
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS       PORTS      NAMES
    2fb0348d746f   centos    "/bin/bash"              10 seconds ago   Up 9 seconds            os1
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@2fb0348d746f /]# ping www.baidu.com
    PING www.a.shifen.com (153.3.238.102) 56(84) bytes of data.
    64 bytes from 153.3.238.102 (153.3.238.102): icmp_seq=1 ttl=127 time=18.8 ms
    64 bytes from 153.3.238.102 (153.3.238.102): icmp_seq=2 ttl=127 time=18.5 ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    容器是如何连通外网的?查询容器网络类型,其中有一个叫做bridge类型的网络连接,这个网络所使用的虚拟交换机(虚拟网桥)就是docker0。容器创建后,相当于容器插了一根网线连接到了docker0虚拟交换机上(linux bridge虚拟交换机),所以容器的ip地址为172.17.0网段(docker0网段为172.17.0网段)。

    [root@docker ~]# ifconfig
    docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
            inet6 fe80::42:41ff:fe39:80cd  prefixlen 64  scopeid 0x20<link>
            ether 02:42:41:39:80:cd  txqueuelen 0  (Ethernet)
            RX packets 39  bytes 4464 (4.3 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 54  bytes 5358 (5.2 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    [root@docker ~]# docker run -tid --name os1 --restart always centos
    86e8046a823ddc53fc717676506e6e7e0c5395d31f1aede01e2de93679b5a9c4
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@86e8046a823d /]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    439: eth0@if440: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    如何查看虚拟交换机?(LinuxBridge 虚拟交换机/OVS 虚拟交换机)

    查询linux bridge 虚拟交换机用 brctl show
    查询ovs虚拟交换机使用 ovs-vsctl show
    [root@docker ~]# brctl show
    -bash: brctl: command not found
    命令没有,直接联网安装即可。
    [root@docker ~]# yum install -y https://mirrors.aliyun.com/centos/7/os/x86_64/Packages/bridge-utils-1.5-9.el7.x86_64.rpm
    [root@docker ~]# brctl show
    bridge name	bridge id		STP enabled	interfaces
    docker0		8000.0242abfc06e8	no		vethe7bbcbe
    看到docker0上多了一个接口:vethe7bbcbe,这个接口就是连接容器使用的接口。
    这个接口名字可以在宿主机上(物理机/虚拟机)通过ip a查到
    [root@docker ~]# ip a |grep veth
    440: vethe7bbcbe@if439: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    会看到,该接口连接到了439号口,439号口是谁呢?
    登录到容器里面查看
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@86e8046a823d /]# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    439: eth0@if440: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
        link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
        inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever
    439号口就是我容器的虚拟网卡对应的网口。
    这时候容器的eth0又连接到了440号口。它就是物理机的vethe7bbcbe。
    他们是一对儿veth pair,这样就建立起了连接。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    自定义网络,创建容器的时候,没有特别指定用哪个网络,默认使用bridge(docker0/172.17.0.1),不想用它默认的这个bridge,可以自己创建一个自己的网络,而且可以上外网。

    [root@docker ~]#  docker network create -d bridge --subnet 192.168.88.0/24 net88
    0356d17e5c4a1a772597a323d82bb90f8d0ec7536568e1d642436ccfc6301533
    自定义网络创建好之后,在宿主机上会显示多一个虚拟交换机。
    [root@docker ~]#  docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    5d9d6632dac4   bridge    bridge    local
    d91318448989   host      host      local
    0356d17e5c4a   net88     bridge    local
    8a522a475a44   none      null      local
    这时候物理机(linux)就会多出一个虚拟网卡:br-0356d17e5c4a,也是linux bridge类型的虚拟交换机。
    [root@docker ~]# ifconfig
    br-0356d17e5c4a: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            inet 192.168.88.1  netmask 255.255.255.0  broadcast 192.168.88.255
            ether 02:42:ea:e4:b5:81  txqueuelen 0  (Ethernet)
            RX packets 12  bytes 990 (990.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 27  bytes 2279 (2.2 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    默认的虚拟交换机为docker0
    docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
            inet6 fe80::42:41ff:fe39:80cd  prefixlen 64  scopeid 0x20<link>
            ether 02:42:41:39:80:cd  txqueuelen 0  (Ethernet)
            RX packets 39  bytes 4464 (4.3 KiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 54  bytes 5358 (5.2 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    通过自定义网络创建容器
    [root@docker ~]#  docker run -tid --name os1 --restart always --network net88 centos
    ab51cefce1dae6004baa01c1493f6261f7f1dfb844c2674f235bfb8a450ec712
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
    ab51cefce1da   centos    "/bin/bash"   4 seconds ago   Up 3 seconds             os1
    [root@docker ~]# docker inspect os1 |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "",
                        "IPAddress": "192.168.88.2",
    验证容器能上外网
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@ab51cefce1da /]# ping www.baidu.com -c 3
    PING www.a.shifen.com (153.3.238.110) 56(84) bytes of data.
    64 bytes from 153.3.238.110 (153.3.238.110): icmp_seq=1 ttl=127 time=18.6 ms
    64 bytes from 153.3.238.110 (153.3.238.110): icmp_seq=2 ttl=127 time=19.4 ms
    64 bytes from 153.3.238.110 (153.3.238.110): icmp_seq=3 ttl=127 time=19.7 ms
    --- www.a.shifen.com ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2002ms
    rtt min/avg/max/mdev = 18.643/19.247/19.671/0.438 ms
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    默认情况下,一台主机上,使用同一个网络,创建多个容器,默认多个容器间网络是互通的;一台主机上,使用不同网络,创建的容器,它们之间是不能直接互通的,可以通过配置路由;
    容器跨主机如何互通?docker提供了一个集群管理软件(容器编排工具swarm),谷歌提供一个容器编排工具 kubernetes=k8s,这些编排工具都可以实现容器跨节点互通,它们是通过三方网络插件(calico/flannal等)来实现。
    容器互联(搭建博客)
    通过本地docker,快速部署一个wordpress博客系统。
    在这里插入图片描述
    1、创建一个mysql容器,在mysql里面单独创建一个数据库,名叫 wordpress,专门给wordpress博客使用。

    [root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_DATABASE=wordpress mysql
    8d8c3d4acd663ca9469987a8b15a47567a45453fbefc558d96655d046abab6ca
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                 NAMES
    8d8c3d4acd66   mysql     "docker-entrypoint.s…"   10 seconds ago   Up 8 seconds    3306/tcp, 33060/tcp   db
    [root@docker ~]# docker inspect db |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.2",
                        "IPAddress": "172.17.0.2",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    [root@docker ~]# mysql -uroot -predhat -h 172.17.0.2
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 8.0.27 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | wordpress          |
    +--------------------+
    5 rows in set (0.002 sec)
    
    MySQL [(none)]> use wordpress;
    Database changed
    MySQL [wordpress]> show tables;
    Empty set (0.001 sec)
    
    MySQL [wordpress]>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2、创建一个wordpress容器,对于wordpress,需要连接到mysql上面,需要哪个账号和密码?Mysql的服务器是什么?所以在wordpress上面要提前录入变量,涉及4个变量:WORDPRESS_DB_HOST 指定wordpress的mysql服务器地址,WORDPRESS_DB_USER 指定wordpress 使用哪个用户连接数据库,WORDPRESS_DB_PASSWORD 指定密码,WORDPRESS_DB_NAME 要写入哪个数据库。
    这个mysql有没有必要让外界可以访问到呢?其实是没有必要的。也就是说别人访问的是wordpress,不需在mysql上做端口映射。只需要在wordpress上做端口映射即可。

    [root@docker ~]# docker pull wordpress
    [root@docker ~]# docker run -tid --name blog --restart always -e WORDPRESS_DB_HOST=172.17.0.2 -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=redhat -e WORDPRESS_DB_NAME=wordpress -p 80:80 wordpress
    fff5f14fa73c3def1c572a1839784a9469b6b03b0eaffe6a6795934e87d35ec8
    -p 前面宿主机端口,后面容器端口
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE       COMMAND                  CREATED              STATUS              PORTS                               NAMES
    fff5f14fa73c   wordpress   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp   blog
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    之后打开浏览器进行博客网页安装,输入宿主机ip地址回车即可,10.1.1.77:80。http默认80端口
    安装后查看wordpress数据库发现多了些数据表。

    [root@docker ~]# mysql -uroot -predhat -h 172.17.0.2
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 38
    Server version: 8.0.27 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> use wordpress;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    MySQL [wordpress]> show tables;
    +-----------------------+
    | Tables_in_wordpress   |
    +-----------------------+
    | wp_commentmeta        |
    | wp_comments           |
    | wp_links              |
    | wp_options            |
    | wp_postmeta           |
    | wp_posts              |
    | wp_term_relationships |
    | wp_term_taxonomy      |
    | wp_termmeta           |
    | wp_terms              |
    | wp_usermeta           |
    | wp_users              |
    +-----------------------+
    12 rows in set (0.002 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    注意:如果数据库版本采用的是5.7,有时候密码策略问题会导致无法登录,按照以下操作流程进行修改即可。

    root@d9952d1aa1fa:/# mysql -u root -prootroot
    mysql> use mysql
    mysql> select host,user,plugin from user where user='root';
    +-----------+------+-----------------------+
    
    | host      | user | plugin                |
    
    +-----------+------+-----------------------+
    
    | %         | root | caching_sha2_password |
    
    | localhost | root | caching_sha2_password |
    
    +-----------+------+-----------------------+
    
    2 rows in set (0.00 sec)
    
    更改密码策略
    mysql> alter user 'root'@'%' identified with mysql_native_password by 'rootroot';
    Query OK, 0 rows affected (0.00 sec)
    mysql> select host,user,plugin from user where user='root';
    +-----------+------+-----------------------+
    
    | host      | user | plugin                |
    
    +-----------+------+-----------------------+
    
    | %         | root | mysql_native_password |
    
    | localhost | root | caching_sha2_password |
    
    +-----------+------+-----------------------+
    
    2 rows in set (0.00 sec)
    mysql> exit
    Bye
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    把数据库容器关闭掉,之后刷新页面,发现系统异常显示数据库未连接。(docker inspect查看容器详细信息)

    [root@docker ~]# docker inspect db |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.2",
                        "IPAddress": "172.17.0.2",
    [root@docker ~]# docker inspect blog |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.3",
                        "IPAddress": "172.17.0.3",
    [root@docker ~]# docker stop db
    db
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    临时创建一个其他容器,比如centos

    [root@docker ~]# docker run -tid --name os1 --restart always centos
    6c6eb41daaf4c7c51d6188852529565150d02f49d7b06e23db16c804dd25a56e
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                               NAMES
    6c6eb41daaf4   centos      "/bin/bash"              3 seconds ago    Up 2 seconds                                        os1
    fff5f14fa73c   wordpress   "docker-entrypoint.s…"   11 minutes ago   Up 11 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   blog
    [root@docker ~]# docker inspect os1 |grep -i ipadd
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.2",
                        "IPAddress": "172.17.0.2",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    会发现,之前db用的ip为172.17.0.2,关闭之后,创建的新的容器,它把172.17.0.2占用了。这时在启动db,看下db的ip地址变了。

    [root@docker ~]# docker start db
    db
    [root@docker ~]# docker inspect db |grep -i ipadd
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.4",
                        "IPAddress": "172.17.0.4",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    现在博客系统不正常,因为在创建wordpress的时候,指定的WORDPRESS_DB_HOST=172.17.0.2 已经写死了。ip地址发生变化了,所以导致无法访问。
    如何避免这种问题呢?在数据库停止期间,不管有多少容器被创建,也不管未来数据库启动时会获取什么ip,上层的应用系统(博客)都是正常的。
    容器互联(–link)
    为了避免底层数据库ip地址发生变化而导致上层应用无法访问,可以使用link的方式指定一个容器别名。给db容器起别名,–link db:memeda,给db容器起个别名叫memeda。之前是通过db容器的ip连接的WORDPRESS_DB_HOST=172.17.0.2,现在是通过db容器的别名memeda连接的,WORDPRESS_DB_HOST=memeda

    [root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_DATABASE=wordpress mysql
    95cadcd677e0a671710ae1758986602344925aec7af50d281ad2a4aa6ae67395
    [root@docker ~]# docker inspect db |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.2",
                        "IPAddress": "172.17.0.2",
    [root@docker ~]# docker run -tid --name blog --restart always --link db:memeda -e WORDPRESS_DB_HOST=memeda -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=redhat -e WORDPRESS_DB_NAME=wordpress -p 80:80 wordpress
    30f861fe93637f7685f510bc4e84f051f61daeba189d2a0f3a1193b810fa79d0
    [root@docker ~]# docker inspect blog |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.3",
                        "IPAddress": "172.17.0.3",
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    测试博客,一切正常。

    接下来,关闭数据库
    [root@docker ~]# docker stop db
    db
    创建一个临时容器占用db容器的 172.17.0.2 ip地址
    [root@docker ~]# docker run -tid --name os1 --restart always centos
    4fcad085b3470ef467255561201e5a9249716e063cc726fbc1986445ae6480e4
    [root@docker ~]# docker inspect os1 |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.2",
                        "IPAddress": "172.17.0.2",
    启动数据库
    [root@docker ~]# docker start db
    db
    [root@docker ~]# docker inspect db |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.4",
                        "IPAddress": "172.17.0.4",
    确认容器db的ip地址发生变化,刷新博客正常。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6、容器数据卷的管理

    容器默认卷管理不能持久化保存数据,当把容器删除后,物理主机上的数据也会随之删除。

    [root@docker ~]# docker exec -ti os1 /bin/bash
    容器里面新增了一个文件
    [root@186445e7abb5 /]# cd /tmp
    [root@186445e7abb5 tmp]# touch 1.txt
    这个文件是在容器里面新增的,它会映射到物理主机上。
    [root@docker ~]# find / -name 1.txt     差分卷(差分数据)
    /var/lib/docker/overlay2/29ae59551f8e77b175d5c518802499910f3f1bdcc825076475906850489753c1/diff/tmp/1.txt
    /var/lib/docker/overlay2/29ae59551f8e77b175d5c518802499910f3f1bdcc825076475906850489753c1/merged/tmp/1.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    以centos容器为例,docker的默认存储路径位于/var/lib/docker,其中containers文件夹保存着容器的相关信息,image保存着镜像的相关信息,overlay2保存着容器虚拟文件系统的相关信息。overlay2中有diff目录和merged目录,diff中保存的就是差分信息,merged是在容器运行时才会出现的存储情况集合,我们可以直接对差分信息进行修改,也可以在merged中进行修改,修改后的结果也会出现在diff中,同时容器内部也会直观的看到我们的修改内容。

    当把容器删除后,物理主机上的数据也会随之删除。
    [root@docker ~]# docker rm -f os1
    os1
    [root@docker ~]#  find / -name 1.txt
    
    • 1
    • 2
    • 3
    • 4

    默认情况下,容器写入的数据,会被保存在容器层,随着容器删除而删除;这时候可以将容器文件和物理主机某个文件进行绑定映射,这样删除容器,数据就会保留下来。
    手工指定容器永久卷,有两种映射方式:1、-v /data (如果-v参数后面只带了一个目录,那么该目录表示的是容器目录,会在宿主机上随机分配目录进行映射) 2、-v /host_dir:/docker_dir(指定映射目录,左边是宿主机目录,右边是容器目录)

    [root@docker ~]# docker run -tid --name os1 --restart always -v /abc centos
    9c5e4ff5de827814bd0f713d91eb48d5905b2662968e4d0eedcbdf95e0439262
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS        PORTS     NAMES
    9c5e4ff5de82   centos    "/bin/bash"   1 second ago   Up 1 second             os1
    [root@docker ~]# docker exec -ti os1 /bin/bash
    接下来,往容器/abc目录里面写数据
    [root@9c5e4ff5de82 /]# cd /abc/
    [root@9c5e4ff5de82 abc]# touch abc.txt
    [root@9c5e4ff5de82 abc]# ls
    abc.txt
    这个文件在容器里面,它会映射到物理主机哪个目录呢?
    [root@docker ~]# find / -name abc.txt
    /var/lib/docker/volumes/78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3/_data/abc.txt
    查询容器的详细信息inspect
    [root@docker ~]# docker inspect os1
    "Mounts": [
                {
                    "Type": "volume",
                    "Name": "78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3",
                    "Source": "/var/lib/docker/volumes/78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3/_data",
                    "Destination": "/abc",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    指定了-v参数后,如果只有一个目录,代表容器目录,它会在宿主机上随机生成一个目录,但是随机生成的这个目录是永久的。删除容器后会发现,容器里面之前的数据,依然在宿主机上保存着。

    [root@docker ~]# docker rm -f os1
    os1
    [root@docker ~]# find / -name abc.txt
    /var/lib/docker/volumes/78194401333e91063f4260f2fa45a12ea984a889a19ebf80101e4617fc4cf3d3/_data/abc.txt
    
    • 1
    • 2
    • 3
    • 4

    如果这时候再次创建这个容器,指定/abc目录,那么容器里面可以看到之前的内容吗?
    不能看到之前内容。原因是因为,每次创建容器时随机映射分配的宿主机目录根本就不是同一个。

    [root@docker ~]# docker run -tid --name os2 --restart always -v /abc centos
    [root@docker ~]# docker exec -ti os2 /bin/bash
    root@e489940d9af0:/# cd /abc/
    root@e489940d9af0:/data# ls
    
    • 1
    • 2
    • 3
    • 4

    手工指定映射目录,-v /host_dir:/docker_dir(左边是宿主机目录,右边是容器目录)

    [root@docker ~]# docker run -tid --name os1 --restart always -v /host_dir:/docker_dir centos
    bf41a5d2118e3af3393659d3401786b46908577488b90172ff67522c36da4049
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS   NAMES
    bf41a5d2118e   centos      "/bin/bash"              4 seconds ago   Up 2 seconds           os1
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@bf41a5d2118e /]# cd /docker_dir
    [root@bf41a5d2118e docker_dir]# touch 1.txt
    [root@bf41a5d2118e docker_dir]# ls
    1.txt
    [root@bf41a5d2118e docker_dir]# exit
    exit
    [root@docker ~]# ls /host_dir
    1.txt
    接下来删除容器
    [root@docker ~]# docker rm -f os1
    os1
    [root@docker ~]# ls /host_dir
    1.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    后面创建容器的时候,也可以复用之前容器映射在宿主机上的目录
    [root@docker ~]# docker run -tid --name os2 --restart always -v /host_dir:/docker_dir centos
    daf3dcdabab0593afff5ced8e75b74c57e62b35df7070d672da869a73ebd4142
    [root@docker ~]# docker exec -ti os2 /bin/bash
    [root@daf3dcdabab0 /]# ls /docker_dir
    1.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    目录的复用,宿主机映射目录的数据可供多个容器共用,创建mysql数据库

    [root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -v /host_data/:/var/lib/mysql mysql
    68ba945c42da1fb109c60e21b597c39b04ef626bfa7851448deba31c5b51fe61
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                NAMES                                                              
    68ba945c42da   mysql     "docker-entrypoint.s…"   6 seconds ago   Up 4 seconds   3306/tcp, 33060/tcp   db
    [root@docker ~]# ls /host_data
     68ba945c42da.err   ca.pem               ibdata1         mysql.ibd            sys
     auto.cnf           client-cert.pem      ib_logfile0     performance_schema   undo_001
     binlog.000001      client-key.pem       ib_logfile1     private_key.pem      undo_002
     binlog.000002     '#ib_16384_0.dblwr'   ibtmp1          public_key.pem
     binlog.index      '#ib_16384_1.dblwr'  '#innodb_temp'   server-cert.pem
     ca-key.pem         ib_buffer_pool       mysql           server-key.pem
     因为mysql数据目录/var/lib/mysql映射到了宿主机上,所以mysql的所有数据文件日志文件等都保存在了宿主机上。
     登录数据库并操作
    [root@docker ~]# docker inspect db |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.2",
                        "IPAddress": "172.17.0.2",
    [root@docker ~]# mysql -uroot -predhat -h172.17.0.2
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 8.0.27 MySQL Community Server - GPL
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> create database abc;
    Query OK, 1 row affected (0.002 sec)
    
    MySQL [(none)]> use abc;
    Database changed
    MySQL [abc]> show tables;
    Empty set (0.001 sec)
    
    MySQL [abc]> create table memeda(id int);
    Query OK, 0 rows affected (0.007 sec)
    
    MySQL [abc]>  insert into memeda values(1);
    Query OK, 1 row affected (0.004 sec)
    
    MySQL [abc]> insert into memeda values(2);
    Query OK, 1 row affected (0.001 sec)
    
    MySQL [abc]> insert into memeda values(3);
    Query OK, 1 row affected (0.001 sec)
    
    MySQL [abc]> select * from memeda;
    +------+
    | id   |
    +------+
    |    1 |
    |    2 |
    |    3 |
    +------+
    3 rows in set (0.000 sec)
    
    MySQL [abc]> exit;
    Bye
    
    [root@docker ~]# ls /host_data/     有刚才创建的abc数据库目录了
     68ba945c42da.err   ca.pem               ib_logfile1          server-cert.pem
     abc                client-cert.pem      ibtmp1               server-key.pem
     auto.cnf           client-key.pem      '#innodb_temp'        sys
     binlog.000001     '#ib_16384_0.dblwr'   mysql                undo_001
     binlog.000002     '#ib_16384_1.dblwr'   mysql.ibd            undo_002
     binlog.000003      ib_buffer_pool       performance_schema
     binlog.index       ibdata1              private_key.pem
     ca-key.pem         ib_logfile0          public_key.pem
    删除容器
    [root@docker ~]# docker rm -f db
    db
    删除容器后,宿主机上映射的目录的数据还在。
    [root@docker ~]# ls /host_data/
     68ba945c42da.err   ca.pem               ib_logfile1          server-cert.pem
     abc                client-cert.pem      ibtmp1               server-key.pem
     auto.cnf           client-key.pem      '#innodb_temp'        sys
     binlog.000001     '#ib_16384_0.dblwr'   mysql                undo_001
     binlog.000002     '#ib_16384_1.dblwr'   mysql.ibd            undo_002
     binlog.000003      ib_buffer_pool       performance_schema
     binlog.index       ibdata1              private_key.pem
     ca-key.pem         ib_logfile0          public_key.pem
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    下次可以直接通过映射关系,把宿主机的数据映射到容器里面
    [root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=redhat -v /host_data/:/var/lib/mysql mysql
    4c62e5e6dda99a1aebadc3d707a3de40da2c499c70019382e309eb66e270df5c
    [root@docker ~]# mysql -uroot -predhat -h172.17.0.2
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 8.0.27 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | abc                |
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    5 rows in set (0.002 sec)
    
    MySQL [(none)]> use abc;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    MySQL [abc]> select * from memeda;
    +------+
    | id   |
    +------+
    |    1 |
    |    2 |
    |    3 |
    +------+
    3 rows in set (0.000 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    7、自定义镜像

    利用dockerfile文件导入基础镜像,后通过docker build创建自定义镜像。
    默认centos是不包含比如vim/ifconfig等,很多命令没有安装。默认centos的yum源是不能下载的,要配置过期的yum源vault。编写一个dockerfile文件进行相关定义:

    了解dockerfile如何编写
    https://developer.aliyun.com/mirror/centos-vault?spm=a2c6h.13651104.0.0.2705320cAjPIus
    
    • 1
    • 2
    [root@docker ~]# vim dockerfile
    [root@docker ~]# cat dockerfile
    FROM centos:latest
    MAINTAINER mpp
    RUN minorver=8.4.2105 \
    && sed -e "s|^mirrorlist=|#mirrorlist=|g" -e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.aliyun.com/centos-vault/$minorver|g" -i.bak /etc/yum.repos.d/CentOS-*.repo
    RUN yum install -y vim net-tools iproute zip unzip bzip2
    
    CMD ["/bin/bash"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    FROM 导入本地哪个基础镜像,MAINTAINER (可选)维护者,RUN 运行linux命令(临时启用一个容器运行命令,用完就删除),RUN可以有多个(一条RUN指令后面可以执行多条命令,命令之间使用“&&”隔开,使用RUN指令如果要进行换行需使用“\”。每执行一次RUN指令,镜像就会增加一层),CMD 基础镜像在封装时会带上CMD告诉容器未来运行哪个进程。指定一个容器启动时要运行的命令,dockerfile中可以有多个CMD指令,但只有最后一个生效。RUN是在构建镜像时使用,CMD是在运行容器时使用。

    -t指-tag标签版本,通过当前路径下(.点代表当前路径)的默认标准文件名称dockerfile来创建自定义镜像。centos:vim
    .点代表当前路径下,会自动加载默认的文件名dockerfile,不是这个文件名需要 -f 指定文件
    [root@docker ~]# docker build -t centos:vim .
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    centos       vim       f1209324e065   7 hours ago     309MB
    centos       latest    5d0da3dc9764   2 years ago     231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    [root@docker ~]# docker run -tid --name os1 --restart always centos:vim
    ddf3e4371ccee09a52a1713779420974aa1f1dadba4801a1432871b545dea11c
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@ddf3e4371cce /]# ifconfig
    进入容器后就能用vim、ifconfig等命令了
    
    • 1
    • 2
    • 3
    • 4
    • 5

    扩展:(自行百度了解)
    1.如何将容器打包成镜像,docker commit os1 centos:txt

    docker commit,提交容器的副本,让这个容器产生一个新的镜像。
    [root@docker ~]# docker run -tid --name os1 --restart always centos
    9376b2d648d5dceedfaca28fd922f87bd4d856531dcc37e69d9e58ac40298032
    [root@docker ~]# docker exec -ti os1 /bin/bash
    [root@9376b2d648d5 /]# ls
    bin  etc   lib    lost+found  mnt  proc  run   srv  tmp  var
    dev  home  lib64  media       opt  root  sbin  sys  usr
    [root@9376b2d648d5 /]# vi 1.txt
    [root@9376b2d648d5 /]# cat 1.txt
    111
    222
    333
    [root@9376b2d648d5 /]# exit
    exit
    [root@docker ~]# docker commit os1 centos:txt
    sha256:15b4ccec3d33ca9fa50d90346dbec591554714c0c5186d838d4ae0e0fec3f525
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    centos       txt       15b4ccec3d33   10 seconds ago   231MB
    centos       latest    5d0da3dc9764   2 years ago      231MB
    [root@docker ~]# docker run -tid --name os2 --restart always centos:txt
    fccd1bd70cfcc962b409df8f777241a3d137406556014b21d5c3c4d1090293d0
    [root@docker ~]# docker exec -ti os2 /bin/bash
    [root@fccd1bd70cfc /]# ls
    1.txt  dev  home  lib64       media  opt   root  sbin  sys  usr
    bin    etc  lib   lost+found  mnt    proc  run   srv   tmp  var
    [root@fccd1bd70cfc /]# cat 1.txt
    111
    222
    333
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    2.如何利用官方scratch空镜像,从头构建自己的基础镜像(一般基础镜像由厂家提供)
    ADD和COPY参数
    ADD和COPY文件,效果相同,将宿主机上的文件拷贝到镜像中。

    先把dockerfile复制一份dockerfile02
    [root@docker ~]# vim dockerfile02
    [root@docker ~]# cat dockerfile02
    FROM centos:vim
    MAINTAINER mpp
    RUN mkdir /add /copy
    ADD 1.txt /add
    COPY 1.txt /copy
    
    CMD ["/bin/bash"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    把当前路径下的1.txt 文件添加到/add复制到/copy目录下
    .点代表当前路径下,会自动加载默认的文件名dockerfile,不是这个文件名需要 -f 指定文件
    [root@docker ~]# docker build -t centos:add . -f dockerfile02
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    centos       add       53f4ccb30559   6 seconds ago   309MB
    centos       vim       f1209324e065   7 hours ago     309MB
    centos       latest    5d0da3dc9764   2 years ago     231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [root@docker ~]# docker run -tid --name os2 --restart always centos:add
    ea9920ca38bfea9f26020ddea4b9878750674e7e12c6751e8f38939ef66d24df
    [root@docker ~]# docker exec -ti os2 /bin/bash
    [root@ea9920ca38bf /]# ls /add
    1.txt
    [root@ea9920ca38bf /]# ls /copy
    1.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ADD和COPY压缩包,效果不同,将宿主机上的文件拷贝到镜像中。
    ADD可以将tar、gz等格式的压缩包在拷贝到镜像中后自动解压,并将压缩包从镜像中删除。
    不管是tar,还是tar.gz,通过add参数添加,会自动解压;而copy参数是原封不动的进行压缩包复制。

    [root@docker ~]# touch 1.txt 2.txt 3.txt
    [root@docker ~]# tar -cvf 123.tar *.txt
    [root@docker ~]# tar -zcvf 123.tar.gz *.txt
    [root@docker ~]# cp dockerfile02 dockerfile03
    [root@docker ~]# ls
    123.tar     1.txt  3.txt            dockerfile    dockerfile03
    123.tar.gz  2.txt  anaconda-ks.cfg  dockerfile02
    [root@docker ~]# vim dockerfile03
    [root@docker ~]# cat dockerfile03
    FROM centos:vim
    MAINTAINER mpp
    RUN mkdir /add_tar /add_targz /copy_tar /copy_targz
    ADD 123.tar /add_tar
    ADD 123.tar.gz /add_targz
    COPY 123.tar /copy_tar
    COPY 123.tar.gz /copy_targz
    
    CMD ["/bin/bash"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    [root@docker ~]# docker build -t centos:targz . -f dockerfile03
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    centos       targz     4cf38f3ea435   6 seconds ago    309MB
    centos       add       53f4ccb30559   19 minutes ago   309MB
    centos       vim       f1209324e065   7 hours ago      309MB
    centos       latest    5d0da3dc9764   2 years ago      231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    [root@docker ~]# docker run -tid --name os3 --restart always centos:targz
    8744ad51630c1ae1e7d61d479820c1956a5c7398b452ece7bf596b462306e541
    [root@docker ~]# docker exec -ti os3 /bin/bash
    [root@8744ad51630c /]# ls /add_tar
    1.txt  2.txt  3.txt
    [root@8744ad51630c /]# ls /copy_tar
    123.tar
    [root@8744ad51630c /]# ls /add_targz
    1.txt  2.txt  3.txt
    [root@8744ad51630c /]# ls /copy_targz
    123.tar.gz
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    配置一个nginx自定义镜像

    [root@docker ~]# cp dockerfile03 dockerfile04
    [root@docker ~]# vim dockerfile04
    [root@docker ~]# cat dockerfile04
    FROM centos:vim
    MAINTAINER mpp
    RUN yum install nginx -y
    
    CMD ["nginx","-g","daemon off;"]
    
    查看nginx历史信息,加参数--no-trunc显示全部信息(--no-trunc,不截断)
    docker history nginx:latest --no-trunc | head -2 显示前两行全部信息
    CMD ["nginx","-g","daemon off;"]   参数之间要用逗号隔开
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    [root@docker ~]# docker build -t centos:nginx . -f dockerfile04
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    centos       nginx     93a08c93aa8d   3 minutes ago   388MB
    centos       targz     4cf38f3ea435   6 hours ago     309MB
    centos       add       53f4ccb30559   6 hours ago     309MB
    centos       vim       f1209324e065   13 hours ago    309MB
    centos       latest    5d0da3dc9764   2 years ago     231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [root@docker ~]# docker run -tid --name web --restart always -p 80:80 centos:nginx
    c91c06e80fa7d187221b5501ece9b26f59c447576216051efdbea6e0cedbc948
    [root@docker ~]# docker exec -ti web /bin/bash
    [root@c91c06e80fa7 /]# cd /usr/share/nginx/html
    [root@c91c06e80fa7 html]# ls
    404.html  50x.html  index.html  nginx-logo.png  poweredby.png
    [root@c91c06e80fa7 html]# echo 222 > index.html
    网页访问,http://10.1.1.77/    http默认80端口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ENV在dockerfile中指定环境变量,等同于-e指定环境变量

    [root@docker ~]# cp dockerfile03 dockerfileenv
    [root@docker ~]# vim dockerfileenv
    [root@docker ~]# cat dockerfileenv
    FROM centos:vim
    MAINTAINER mpp
    ENV abc=hehehe
    
    CMD ["/bin/bash"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [root@docker ~]# docker build -t centos:env . -f dockerfileenv
    [root@docker ~]# docker run -tid --name osenv --restart always centos:env
    1db34007500a8199f971a8616c13b7955b17d3904145e6531e47dca8c506a7d6
    [root@docker ~]# docker exec -ti osenv /bin/bash
    [root@1db34007500a /]# echo $abc
    hehehe
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用VOLUME指令将容器中的文件或目录挂载到宿主机上,使用VOLUME指令挂载的文件或目录自动映射到宿主机的/var/lib/docker/volumes/volume name/_data目录下,删除容器时,由容器映射出来的数据默认不会同时被删除;如果需要同时删除,需要在删除容器时添加-v选项。
    VOLUME是docker在镜像中指定好了,未来容器要映射的容器中具体目录,而RUN mkdir 仅仅是在容器里面单独创建一个目录。

    [root@docker ~]# cp dockerfile03 dockerfilevolume
    [root@docker ~]# vim dockerfilevolume
    [root@docker ~]# cat dockerfilevolume
    FROM centos:vim
    MAINTAINER mpp
    VOLUME /data
    
    CMD ["/bin/bash"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [root@docker ~]# docker build -t centos:volume . -f dockerfilevolume
    [root@docker ~]# docker run -tid --name osvolume --restart always centos:volume
    [root@docker ~]# docker exec -ti osvolume /bin/bash
    [root@160bf71e71da /]# ls /data/
    [root@160bf71e71da /]# exit
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    USER在dockerfile中指定进入容器用户,默认进入容器是root用户身份

    [root@docker ~]# cp dockerfile03 dockerfile05
    [root@docker ~]# vim dockerfile05
    [root@docker ~]# cat dockerfile05
    FROM centos:vim
    MAINTAINER mpp
    RUN yum install passwd -y
    RUN useradd tom
    RUN echo "redhat" |passwd tom --stdin
    RUN echo "redhat" |passwd root --stdin
    USER tom
    
    CMD ["/bin/bash"]
    
    USER tom  使用tom用户登入容器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    [root@docker ~]# docker build -t centos:user . -f dockerfile05
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    centos       user      32dcb820a322   12 seconds ago   324MB
    centos       nginx     93a08c93aa8d   18 minutes ago   388MB
    centos       targz     4cf38f3ea435   6 hours ago      309MB
    centos       add       53f4ccb30559   6 hours ago      309MB
    centos       vim       f1209324e065   13 hours ago     309MB
    centos       latest    5d0da3dc9764   2 years ago      231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    [root@docker ~]# docker run -tid --name os5 --restart always centos:user
    d7a20c6d18f47e6cd0ee25dba43235e76f2f943708c895c3021da3d1e3a6bb1a
    [root@docker ~]# docker exec -ti os5 /bin/bash
    [tom@d7a20c6d18f4 /]$ whoami
    tom
    [tom@d7a20c6d18f4 /]$ su - root
    Password:
    [root@d7a20c6d18f4 ~]# exit
    logout
    [tom@d7a20c6d18f4 /]$ exit
    exit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    配置SSH镜像,EXPOSE 指镜像启动时暴露的端口,如果要指定端口协议,格式为“EXPOSE 端口号/协议”,例如:“EXPOSE 80/tcp”

    [root@docker ~]# cp dockerfile05 dockerfile06
    [root@docker ~]# vim dockerfile06
    [root@docker ~]# cat dockerfile06
    FROM centos:latest
    MAINTAINER mpp
    RUN minorver=8.4.2105 \
    && sed -e "s|^mirrorlist=|#mirrorlist=|g" -e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.aliyun.com/centos-vault/$minorver|g" -i.bak /etc/yum.repos.d/CentOS-*.repo
    RUN yum install -y vim net-tools iproute passwd openssh-clients openssh-server
    RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
    RUN ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key
    RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
    RUN echo "root:redhat" | chpasswd
    EXPOSE 22
    
    CMD ["/usr/sbin/sshd","-D"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    [root@docker ~]# docker build -t centos:ssh . -f dockerfile06
    [root@docker ~]# docker images
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    centos       ssh       62e9b602c09e   9 seconds ago    330MB
    centos       user      32dcb820a322   8 minutes ago    324MB
    centos       nginx     93a08c93aa8d   26 minutes ago   388MB
    centos       targz     4cf38f3ea435   6 hours ago      309MB
    centos       add       53f4ccb30559   6 hours ago      309MB
    centos       vim       f1209324e065   13 hours ago     309MB
    centos       latest    5d0da3dc9764   2 years ago      231MB
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [root@docker ~]# docker run -tid --name os6 --restart always centos:ssh
    e40ed8e5cd0d054cd9014a4090b76046cebe38cf1027c7e52532cc358e9af97c
    [root@docker ~]# docker inspect os6 |grep -i ipaddr
                "SecondaryIPAddresses": null,
                "IPAddress": "172.17.0.7",
                        "IPAddress": "172.17.0.7",
    [root@docker ~]# ssh root@172.17.0.7
    The authenticity of host '172.17.0.7 (172.17.0.7)' can't be established.
    ECDSA key fingerprint is SHA256:+AHES0Q2cepCWT0Ut0Lh/Dg65OtCIqNFlDbQKRbTiV4.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '172.17.0.7' (ECDSA) to the list of known hosts.
    root@172.17.0.7's password:
    "System is booting up. Unprivileged users are not permitted to log in yet. Please come back later. For technical details, see pam_nologin(8)."
    [root@e40ed8e5cd0d ~]# cd /etc/ssh
    [root@e40ed8e5cd0d ssh]# ls
    moduli        ssh_host_ecdsa_key      ssh_host_ed25519_key.pub  sshd_config
    ssh_config    ssh_host_ecdsa_key.pub  ssh_host_rsa_key
    ssh_config.d  ssh_host_ed25519_key    ssh_host_rsa_key.pub
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    8、 compose编排

    compose适合针对小场景的容器进行编排操作。把所需要管理的所有的容器,都以yaml文件的格式,写到对应的文件中,之后通过docker compose 命令,去加载这个yaml文件,从而批量化管理所有容器。
    在linux 7 版本里面:docker-compose,linux 7 版本会麻烦些,要安装docker-compose-plugin
    在linux 8 版本里面:docker compose
    以8版本为例,当使用docker compose去执行yaml文件的时候,如果不指定,那么默认加载当前路径下的文件名称为:docker-compose.yaml(标准名称),如果不是这个标准名称,需要带上 -f 参数指定文件名。
    比如上面创建的两个容器,一个mysql,一个wordpress,之前都是通过手工单独管理的,那么现在可以通过compose统一管理。

    yaml文件格式要求:
    1.yaml是以空格缩进来控制层级关系,不能使用Tab键,而且大小写敏感的;(参数遵循小驼峰写法imagePullPolicy)
    2.yaml缩进的空格数量不重要的,重要的是相同层级要左对齐。相同级别的元素,必须有相同的缩进,子元素的缩进距离一定大于父元素。
    3.一组任务列表,列表前要加横线。遇到横线-和冒号:,其后面就空一格(只能用空格缩进不能用tab键来缩进)
    需要注意的是,docker compose的语法格式。

    编写yaml文件
    [root@docker ~]# vim docker-compose.yaml
    [root@docker ~]# cat docker-compose.yaml 
    services:
      blog:
          image: wordpress:latest
          restart: always
          links:
                - db:memeda
          ports:
                - "80:80"
          environment:
                - WORDPRESS_DB_HOST=memeda
                - WORDPRESS_DB_USER=root
                - WORDPRESS_DB_PASSWORD=redhat
                - WORDPRESS_DB_NAME=wordpress
    
      db:
          image: mysql:latest
          restart: always
          environment:
                - MYSQL_ROOT_PASSWORD=redhat
                - MYSQL_DATABASE=wordpress
    
    执行yaml文件,-d 让这个容器在后台运行
    [root@docker ~]# docker compose up -d
    [+] Running 3/3
     ✔ Network root_default   Created 0.3s 
     ✔ Container root-db-1    Started 0.0s 
     ✔ Container root-blog-1  Started 0.0s 
    [root@docker ~]# docker ps
    CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                               NAMES
    9569ac4043f1   wordpress:latest   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   root-blog-1
    3435539d848d   mysql:latest       "docker-entrypoint.s…"   6 seconds ago   Up 6 seconds   3306/tcp, 33060/tcp                 root-db-1
    
    停止服务,# docker compose down
    停止
    [root@docker ~]# docker compose stop
    [+] Stopping 2/2
     ✔ Container root-blog-1  Stopped 3.2s 
     ✔ Container root-db-1    Stopped 0.9s
    
    启动
    [root@docker ~]# docker compose start
    [+] Running 2/2
     ✔ Container root-db-1    Started 0.5s 
     ✔ Container root-blog-1  Started 1.0s
    
    删除运行中容器,-s在删除前停止项目中的所有容器,-f强制删除
    [root@docker ~]# docker compose rm -s -f
    [+] Stopping 2/2
     ✔ Container root-blog-1  Stopped 1.2s 
     ✔ Container root-db-1    Stopped 1.5s 
    Going to remove root-blog-1, root-db-1
    [+] Removing 2/0
     ✔ Container root-db-1    Removed 0.0s 
     ✔ Container root-blog-1  Removed 0.0s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    容器资源限制(内存限制、cpu限制)

    内存限制
    [root@docker ~]# free -m
                  total        used        free      shared  buff/cache   available
    Mem:           3890         388        2940          17         561        3264
    Swap:          4095           0        4095
    [root@docker ~]# docker stats --no-stream
    CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
    58c0bc896043   os2       0.00%     1.578MiB / 3.799GiB   0.04%     656B / 0B   0B / 0B     1
    d3a589160292   os1       0.00%     1.562MiB / 3.799GiB   0.04%     876B / 0B   0B / 0B     1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    cpu限制,cpu主要是限制某个容器的进程必须在哪个cpu上去跑。避免频繁的上下文切换,提升性能。
    在os2里面运行cat命令
    [root@b70a93cdab03 /]# cat /dev/zero > /dev/null &
    [1] 29
    [root@b70a93cdab03 /]# cat /dev/zero > /dev/null &
    [2] 30
    [root@b70a93cdab03 /]# cat /dev/zero > /dev/null &
    [3] 31
    [root@docker ~]# ps -aux |grep cat
    root        2500 94.9  0.0  23184  1468 ?        R    11:13   0:19 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2501 95.0  0.0  23184  1368 ?        R    11:13   0:18 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2502 93.3  0.0  23184  1428 ?        R    11:13   0:16 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2504  0.0  0.0  12144  1100 pts/0    R+   11:13   0:00 grep --color=auto cat
    [root@docker ~]# top
    top - 11:13:59 up  2:13,  2 users,  load average: 1.08, 1.23, 1.16
    Tasks: 178 total,   4 running, 174 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  2.8 us, 72.2 sy,  0.0 ni, 20.8 id,  0.0 wa,  2.8 hi,  1.4 si,  0.0 st
    MiB Mem :   3890.4 total,   2917.1 free,    406.8 used,    566.5 buff/cache
    MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.   3245.9 avail Mem
    [root@docker ~]# lscpu
    Architecture:        x86_64
    CPU op-mode(s):      32-bit, 64-bit
    Byte Order:          Little Endian
    CPU(s):              4
    On-line CPU(s) list: 0-3
    Thread(s) per core:  1
    Core(s) per socket:  4
    Socket(s):           1
    NUMA node(s):        1
    [root@docker ~]# ps mo pid,comm,psr $(pgrep cat)
        PID COMMAND         PSR
       2500 cat               -
          - -                 2
       2501 cat               -
          - -                 3
       2502 cat               -
          - -                 0
    
    三个cat进程,分别运行在2、3、0 号cpu上。如果想让某个容器里面所有的进程都运行在同一个cpu上,可以这么操作。
    [root@docker ~]# docker run -tid --name os3 --restart always --cpuset-cpus 0 centos
    [root@docker ~]# docker exec -ti os3 /bin/bash
    [root@1d273d5d10d2 /]# cat /dev/zero > /dev/null &
    [1] 33
    [root@1d273d5d10d2 /]# cat /dev/zero > /dev/null &
    [2] 34
    [root@1d273d5d10d2 /]# cat /dev/zero > /dev/null &
    [3] 35
    [root@docker ~]# ps mo pid,comm,psr $(pgrep cat)                                    
         PID COMMAND         PSR
       2500 cat               -
          - -                 2
       2501 cat               -
          - -                 3
       2502 cat               -
          - -                 0
       2652 cat               -
          - -                 0
       2653 cat               -
          - -                 0
       2654 cat               -
          - -                 0
    [root@docker ~]# ps -aux |grep cat
    root        2500 97.5  0.0  23184  1468 ?        R    11:13   7:37 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2501 97.3  0.0  23184  1368 ?        R    11:13   7:34 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2502 97.0  0.0  23184  1428 ?        R    11:13   7:32 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2652 36.9  0.0  23184  1472 ?        R    11:20   0:15 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2653 33.3  0.0  23184  1476 ?        R    11:20   0:13 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2654 33.1  0.0  23184  1336 ?        R    11:20   0:12 /usr/bin/coreutils --coreutils-prog-shebang=cat /usr/bin/cat /dev/zero
    root        2658  0.0  0.0  12144  1100 pts/0    R+   11:21   0:00 grep --color=auto cat
    [root@docker ~]# kill -9 2502
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
  • 相关阅读:
    Sentinel-2波段合成
    ARM系列 -- 虚拟化(一)
    关于freopen和fclose
    JVM的几个面试重点
    界面控件Telerik UI for WPF——Windows 11主题精简模式提升应用体验
    计算机网络——数据链路层
    K8S:Pod容器中的存储方式及PV、PVC
    独立站“弃购率”太高,做好这几点帮你提高30%转化率
    Github每日精选(第20期):Python 的交互式图形库plotly.py
    【python可视化】python编码规范、标准库与扩展库对象的导入与使用
  • 原文地址:https://blog.csdn.net/ma1782072/article/details/132981084