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

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

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

镜像仓库
推送镜像,因为是往自己的仓库里面推送的,所以推送之前必须要登录仓库和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
推送镜像,华为云,登录华为云生成临时登录链接
没有命名空间,改成了组织,一个账号默认最多创建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

使用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访问。

镜像保存与导入,保存镜像到本地: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

镜像加速器,配置阿里云。默认情况下,下载镜像是从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

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

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 它是一瞬间完成的。
删除一个容器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
当创建容器的时候,默认会直接进入到容器里面,有时仅想把容器创建出来,而不直接登录。
为容器添加后端分离-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

如何进入容器,推荐使用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
创建一个临时容器(用完即删)--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持续运行。
指定容器运行生命周期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
容器启动关闭重启start/stop/restart
[root@docker ~]# docker stop os1
os1
[root@docker ~]# docker start os1
os1
[root@docker ~]# docker restart os1
os1

指定容器环境变量 -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
查看容器中运行的进程信息,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)]> 

注意:当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)]>

为容器进行端口映射-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

在这里插入图片描述
容器和主机之间文件的拷贝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

容器常用命令

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  求帮助

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

容器是如何连通外网的?查询容器网络类型,其中有一个叫做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

如何查看虚拟交换机?(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,这样就建立起了连接。

自定义网络,创建容器的时候,没有特别指定用哪个网络,默认使用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

默认情况下,一台主机上,使用同一个网络,创建多个容器,默认多个容器间网络是互通的;一台主机上,使用不同网络,创建的容器,它们之间是不能直接互通的,可以通过配置路由;
容器跨主机如何互通?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",
[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]>

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

之后打开浏览器进行博客网页安装,输入宿主机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)

注意:如果数据库版本采用的是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

把数据库容器关闭掉,之后刷新页面,发现系统异常显示数据库未连接。(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

在这里插入图片描述
临时创建一个其他容器,比如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",

会发现,之前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",

现在博客系统不正常,因为在创建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",

测试博客,一切正常。

接下来,关闭数据库
[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地址发生变化,刷新博客正常。

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

以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、-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": ""
            }

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

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

如果这时候再次创建这个容器,指定/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

手工指定映射目录,-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
后面创建容器的时候,也可以复用之前容器映射在宿主机上的目录
[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

目录的复用,宿主机映射目录的数据可供多个容器共用,创建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
下次可以直接通过映射关系,把宿主机的数据映射到容器里面
[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)

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
[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"]

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
[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.如何将容器打包成镜像,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

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.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
[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

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"]
[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
[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

配置一个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;"]   参数之间要用逗号隔开
[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
[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端口

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"]
[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

使用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"]
[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

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用户登入容器
[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
[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

配置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"]
[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
[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

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

容器资源限制(内存限制、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
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值