Docker

Docker

学习目标:

  • 掌握Docker基础知识,能够理解Docker镜像与容器的概念
  • 完成Docker安装与启动
  • 掌握Docker镜像与容器相关命令
  • 掌握Tomcat Nginx 等软件的常用应用的安装
  • 掌握docker迁移与备份相关命令
  • 能够运用Dockerfile编写创建容器的脚本
  • 能够搭建与使用docker私有仓库

1 Docker简介

1.1 什么是虚拟化

在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。

在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件   对资源充分利用

虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等。

1.2 什么是Docker

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在[GitHub](https://github.com/docker/docker) 上进行维护。

![](https://img2023.cnblogs.com/blog/3186882/202305/3186882-20230529165022515-1647842922.png)

Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。

Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。

在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

为什么选择Docker?

(1)上手快。

用户只需要几分钟,就可以把自己的程序“Docker化”。Docker依赖于“写时复制”(copy-on-write)模型,使修改应用程序也非常迅速,可以说达到“随心所致,代码即改”的境界。

随后,就可以创建容器来运行应用程序了。大多数Docker容器只需要不到1秒中即可启动。由于去除了管理程序的开销,Docker容器拥有很高的性能,同时同一台宿主机中也可以运行更多的容器,使用户尽可能的充分利用系统资源。

(2)职责的逻辑分类

使用Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。Docker设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署的生产环境一致性。从而降低那种“开发时一切正常,肯定是运维的问题(测试环境都是正常的,上线后出了问题就归结为肯定是运维的问题)”

(3)快速高效的开发生命周期

Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。(通俗一点说,Docker就像一个盒子,里面可以装很多物件,如果需要这些物件的可以直接将该大盒子拿走,而不需要从该盒子中一件件的取。)

(4)鼓励使用面向服务的架构

Docker还鼓励面向服务的体系结构和微服务架构。Docker推荐单个容器只运行一个应用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或者服务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。(当然,可以在一个容器中运行多个应用程序)

1.3 容器与虚拟机比较

下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。

与传统的虚拟机相比,Docker优势体现为启动速度快、占用体积小。

1.4 Docker 组件

1.4.1 Docker服务器与客户端

Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具Docker以及一整套RESTful API。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。

1.4.2 Docker镜像与容器

镜像是构建Docker的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的“构建”部分。镜像是基于联合文件系统的一种层式结构,由一系列指令一步一步构建出来。例如:

添加一个文件;

执行一个命令;

打开一个窗口。

也可以将镜像当作容器的“源代码”。镜像体积很小,非常“便携”,易于分享、存储和更新。

Docker可以帮助你构建和部署容器,你只需要把自己的应用程序或者服务打包放进容器即可。容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。  容器基于镜像启动,一旦容器启动完成后,我们就可以登录到容器中安装自己需要的软件或者服务。

所以Docker容器就是:

一个镜像格式;

一些列标准操作;

一个执行环境。

Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Docker将这个模型运用到自己的设计中,唯一不同的是:集装箱运输货物,而Docker运输软件。

和集装箱一样,Docker在执行上述操作时,并不关心容器中到底装了什么,它不管是web服务器,还是数据库,或者是应用程序服务器什么的。所有的容器都按照相同的方式将内容“装载”进去。

Docker也不关心你要把容器运到何方:我们可以在自己的笔记本中构建容器,上传到Registry,然后下载到一个物理的或者虚拟的服务器来测试,在把容器部署到具体的主机中。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分发,并且尽量通用。

1.4.3 Registry(注册中心)

Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的Registry叫做Docker Hub。用户可以在Docker Hub注册账号,分享并保存自己的镜像(说明:在Docker Hub下载镜像巨慢,可以自己构建私有的Registry)。

https://hub.docker.com/

2 Docker安装与启动

2.1 安装Docker

Docker官方建议在Ubuntu中安装,因为Docker是基于Ubuntu发布的,而且一般Docker出现的问题Ubuntu是最先更新或者打补丁的。在很多版本的CentOS中是不支持更新最新的一些补丁包的。

由于我们学习的环境都使用的是CentOS,因此这里我们将Docker安装到CentOS上。注意:这里建议安装在CentOS7.x以上的版本,在CentOS6.x的版本中,安装前需要安装其他很多的环境而且Docker很多补丁不支持更新。

请直接挂载课程配套的Centos7.x镜像

(1)yum 包更新到最新

sudo yum update

(2)安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

(3)设置yum源为阿里云

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

(4)安装docker

sudo yum install docker-ce

(5)安装后查看docker版本

docker -v

(6)补充ubuntu

# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 手动安装
sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
  
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository \
   "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/ \
  $(lsb_release -cs) \
  stable"
  
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io

2.2 设置ustc的镜像

ustc是老牌的linux镜像服务提供者了,还在遥远的ubuntu 5.04版本的时候就在用。ustc的docker镜像加速器速度很快。ustc docker mirror的优势之一就是不需要注册,是真正的公共服务。

https://lug.ustc.edu.cn/wiki/mirrors/help/docker

编辑该文件:

vi /etc/docker/daemon.json  

更新:使用docker代理源

{
    "registry-mirrors": ["https://dockerhub.icu"]
}

在该文件中输入如下内容:

{
    "registry-mirrors": [  "https://hub-mirror.c.163.com"]
}

# 参考镜像
{
  "registry-mirrors": [
    #"https://registry.docker-cn.com",
    #"https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    #"https://mirror.baidubce.com",
    #"https://cr.console.aliyun.com/" #配置私有仓库
  ]
}

# docker启动失败:Failed to start Docker Application Container Engine.
可能由于格式问题 - daemon.json  

重启服务

sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl stop docker
sudo systemctl start docker

补充git的安装

sudo yum install -y git

2.3 Docker的启动与停止

systemctl命令是系统服务管理器指令

启动docker:

systemctl start docker

停止docker:

systemctl stop docker

重启docker:

systemctl restart docker

查看docker状态:

systemctl status docker

开机启动:

systemctl enable docker

查看docker概要信息

docker info

查看docker帮助文档

docker --help

2.4 docker常用命令

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
  images      List images
  login       Log in to a registry
  logout      Log out from a registry
  search      Search Docker Hub for images
  version     Show the Docker version information
  info        Display system-wide information

Management Commands:
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.10.5)
  compose*    Docker Compose (Docker Inc., v2.18.1)
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  plugin      Manage plugins
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Swarm Commands:
  swarm       Manage Swarm

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Global Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket to connect to
  -l, --log-level string   Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Run 'docker COMMAND --help' for more information on a command.

For more help on how to use Docker, head to https://docs.docker.com/go/guides/

创建docker网络

(1) 创建一个新的docker虚拟网桥,172.33.0网段

docker network create --subnet=172.33.0.0/24 docker-bd0

(2) 查看创建的虚拟网桥

docker network ls

NETWORK ID     NAME         DRIVER    SCOPE
4608e8409547   docker-bd0   bridge    local

(3) 查看虚拟网桥对应的Linux宿主机虚拟网卡

ifconfig

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:97:9b:f1:8f  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

(4) 临时删除docker0网桥(意味着激活docker-bd0网桥)

# 不执行
ifconfig docker0 down
brctl delbr docker0

(5) 重启docker服务

systemctl restart docker

(6) 配置dns服务器

vim /etc/resolv.conf 
修改为如下
# Generated by NetworkManager
nameserver 172.33.0.10
nameserver 8.8.8.8
nameserver 8.8.4.4

桥接如何使用

docker run -d --name mysql --net docker-bd0 --ip 172.33.0.101 -p 3306:3306  -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

创建与容器的共享目录

# 在宿主机中创建/mnt/docker_share 用于存放用来安装的软件
mkdir /mnt/docker_share
cd /mnt/docker_share
# 同时将docker容器中的所有软件以及数据都放在 /opt 中用于共享
cd /opt

3 常用命令

3.1 镜像相关命令

3.1.1 查看镜像 images

docker images

REPOSITORY:镜像名称

TAG:镜像标签

IMAGE ID:镜像ID

CREATED:镜像的创建日期(不是获取该镜像的日期)

SIZE:镜像大小

这些镜像都是存储在Docker宿主机的/var/lib/docker目录下

如果你需要从网络中查找需要的镜像,可以通过以下命令搜索

docker search 镜像名称

NAME:仓库名称

DESCRIPTION:镜像描述

STARS:用户评价,反应一个镜像的受欢迎程度

OFFICIAL:是否官方

AUTOMATED:自动构建,表示该镜像由Docker Hub自动构建流程创建的

3.1.3 拉取镜像 pull

拉取镜像就是从中央仓库中下载镜像到本地

docker pull 镜像名称

例如,我要下载centos7镜像

docker pull centos:7

3.1.4 删除镜像 rmi

按镜像ID删除镜像

docker rmi 镜像ID

删除所有镜像

docker rmi `docker images -q`

3.2 容器相关命令

3.2.1 查看容器 ps

查看正在运行的容器

docker ps

查看所有容器

docker ps –a

查看最后一次运行的容器

docker ps –l

查看停止的容器

docker ps -f status=exited

3.2.2 创建与启动容器 run

创建容器常用的参数说明:

创建容器命令:docker run

-i:表示运行容器

-t:表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即分配一个伪终端。

--name :为创建的容器命名。

-v:表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录),可以使用多个-v做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后共享到容器上。

-d:在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不会自动登录容器,如果只加-i -t两个参数,创建后就会自动进去容器)。

-p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p做多个端口映射

(1)交互式方式创建容器

docker run -it --name=容器名称 镜像名称:标签 /bin/bash

这时我们通过ps命令查看,发现可以看到启动的容器,状态为启动状态

退出当前容器

exit

(2)守护式方式创建容器:

docker run -di --name=容器名称 镜像名称:标签

登录守护式容器方式:

docker exec -it 容器名称 (或者容器ID)  /bin/bash

3.2.3 停止与启动容器 stop start

停止容器:

docker stop 容器名称(或者容器ID)

启动容器:

docker start 容器名称(或者容器ID)

3.2.4 文件拷贝 docker cp

如果我们需要将文件拷贝到容器内可以使用cp命令

docker cp 需要拷贝的文件或目录 容器名称:容器目录

也可以将文件从容器内拷贝出来

docker cp 容器名称:容器目录 需要拷贝的文件或目录

3.2.5 目录挂载 -v

我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件从而去影响容器。
创建容器 添加-v参数 后边为 宿主机目录:容器目录,例如:

docker run -di -v /usr/local/myhtml:/usr/local/myhtml --name=mycentos3 centos:7

如果你共享的是多级的目录,可能会出现权限不足的提示。

这是因为CentOS7中的安全模块selinux把权限禁掉了,我们需要添加参数 --privileged=true 来解决挂载的目录没有权限的问题

数据卷容器概念

1.创建启动c3数据卷容器,使用–v 参数设置数据卷
docker run –it --name=c3 –v /volume centos:7 /bin/bash

2. 创建启动c1 c2 容器,使用–-volumes-from 参数设置数据卷
docker run –it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run –it --name=c2 --volumes-from c3 centos:7 /bin/bash

3.2.6 查看容器IP地址 inspect

我们可以通过以下命令查看容器运行的各种数据

docker inspect 容器名称(容器ID) 

也可以直接执行下面的命令直接输出IP地址

docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称(容器ID)

3.2.7 删除容器 rm

删除指定的容器:

docker rm 容器名称(容器ID)

4 应用部署

可进入此网站构建dockerfile文件 https://hub.docker.com/

4.1 MySQL部署

参考: https://www.cnblogs.com/niunafei/p/12803829.html

(1)拉取mysql镜像

docker pull centos/mysql-57-centos7

(2)创建容器,设置端口映射、目录映射

docker run -di --name=mysql -p 33306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

或者
# 在/root目录下创建mysql目录用于存储mysql数据信息
mkdir /opt/mysql
cd /opt/mysql

docker run \
--restart always \
-p 3306:3306 \
-v /opt/mysql/conf:/etc/mysql/conf.d \
-v /opt/mysql/logs:/var/log/mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_DATABASE=data \
-e MYSQL_ROOT_PASSWORD=123456 \
-d -it --name mysql centos/mysql-57-centos7

参数说明:

  • -p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
  • -v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
  • -v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
  • -v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
  • -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。

(3) 进入容器,操作mysql

docker exec –it c_mysql /bin/bash

(4)远程登录mysql

连接宿主机的IP ,指定端口为3306

1573636765632

4.2 tomcat部署

(1)拉取镜像

docker pull tomcat:7-jre7
或者
docker pull tomcat:9

(2)创建容器,设置端口映射、目录映射

(说明:这里的war或者jar项目放在webapps下面)
# 在/root目录下创建tomcat目录用于存储tomcat数据信息
mkdir ~/tomcat
cd ~/tomcat


docker run -di \ 
--name=mytomcat \  
-p 9001:8080 \ 
-v $PWD:/usr/local/webapps:/usr/local/tomcat/webapps  \ 
tomcat:9

参数说明:

  • -p 8080:8080:将容器的8080端口映射到主机的8080端口

    -v $PWD:/usr/local/tomcat/webapps:将主机中当前目录挂载到容器的webapps

(3) 使用外部机器访问tomcat

1573649804623

4.3 Nginx部署

(1)拉取镜像

docker pull nginx

(2)创建容器,设置端口映射、目录映射

docker run -di --name=mynginx -p 80:80 nginx
或者
# 在/root目录下创建nginx目录用于存储nginx数据信息
mkdir ~/nginx
cd ~/nginx
mkdir conf
cd conf
# 在~/nginx/conf/下创建nginx.conf文件,粘贴下面内容
vim nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs:/var/log/nginx \
-v $PWD/html:/usr/share/nginx/html \
nginx

(3)nginx的使用

# 在本地设置的html文件夹直接映射到nginx的html文件夹下,可以直接运行项目
docker cp html nginx-1(镜像名):/usr/share/nginx/

(4) 使用外部机器访问nginx

1573652396669

4.4 Redis部署

参考: https://blog.csdn.net/weixin_45821811/article/details/116211724

(1)拉取镜像

docker pull redis:5.0

(2)创建容器,设置端口映射

docker run -di --name=myredis -p 6379:6379 redis:5.0

或者
docker run -di  --name= myredis \
				--restart=always \
--log-opt max-size=100m --log-opt max-file=2 \
				-p 6379:6379  \ 
-v /home/redis/myredis/myredis.conf:/etc/redis/redis.conf  \ 
-v /home/redis/myredis/data:/data \
-d redis redis-server /etc/redis/redis.conf   \ 
--appendonly yes  --requirepass 000415

(3)使用外部机器连接redis

./redis-cli.exe -h 192.168.149.135 -p 6379

4.5 MongoDB部署

参考 : https://blog.csdn.net/u013302168/article/details/121111750

(1)拉取镜像

docker pull mongo

(2)创建容器

未持久化
docker run -itd --name mongo -p 27017:27017 mongo --auth
持久化
docker run -id -p 27018:27017 -v /usr/local/mongodb/data:/data/db --name=mongodb-1 mongo

(3)进入容器

docker exec -it mongo mongo admin

创建账号
db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
db.auth('admin', '123456')

4.6 postgresql部署

(1)拉取镜像

docker pull postgres:14

(2)创建容器

docker run -di --name=postgresql-1 -v /usr/local/postgresql/data:/var/lib/postgresql -e POSTGRES_PASSWORD=123456 -d -p 5432:5432 postgres:14 

(3)使用容器

docker exec -it postgresql-1 bash
su postgres
psql -U postgres -W
exit

5 迁移与备份

5.1 容器保存为镜像 commit

我们可以通过以下命令将容器保存为镜像

docker commit mynginx mynginx_i
docker commit  1d02dfb603a3 django_uwsgi_docker_image 

5.2 镜像备份 save

我们可以通过以下命令将镜像保存为tar 文件

docker  save -o mynginx.tar mynginx_i
docker save -o django_uwsgi_docker_image.tar django_uwsgi_docker_image

5.3 镜像恢复与迁移 load

首先我们先删除掉mynginx_img镜像 然后执行此命令进行恢复

docker load -i mynginx.tar
docker load -i django_uwsgi_docker_image.tar

-i 输入的文件

执行后再次查看镜像,可以看到镜像已经恢复

6 Dockerfile

6.1 什么是Dockerfile

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。

1、对于开发人员:可以为开发团队提供一个完全一致的开发环境;
2、对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfile文件构建一个新的镜像开始工作了;
3、对于运维人员:在部署时,可以实现应用的无缝移植。

6.2 常用命令

# 指定dockerfile基于那个image构建 - 没有会自己创建
FROM centos
FROM python3.9

# 用来标明这个dockerfile谁写的 - 作者
MAINTAINER wykang

# 用来标明dockerfile的标签
LABEL python

# 容器内,切换工作目录,没有会自动创建,没有 / 会在当前路径下创建
WORKDIR /project

# build的时候添加文件到image中
COPY /home/project/requirements.txt requirements.txt
# build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务 - 会自动解压
ADD /home/Django-3.2.5.tar /project

# 容器类执行的命令
RUN pip install r requirements.txt 

# 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"]
VOLUME /project /project
EXPOSE 8000
CMD python manage.py runserver 0:8000


# 配置python
ENV PYTHON_VERSION 3.9.1
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

关键字 作用 备注
FROM 指定父镜像 指定dockerfile基于那个image构建
MAINTAINER 作者信息 用来标明这个dockerfile谁写的
LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"]
CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build的时候复制文件到image中
ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

6.3 使用脚本创建镜像

步骤:

(1)创建目录

mkdir –p /usr/local/dockerjdk8

(2)下载jdk-8u171-linux-x64.tar.gz并上传到服务器(虚拟机)中的/usr/local/dockerjdk8目录

(3)创建文件Dockerfile vi Dockerfile (文件名是固定Dockerfile` )

#依赖镜像名称和ID
FROM centos:7
#指定镜像创建者信息
MAINTAINER ITCAST
#切换工作目录
WORKDIR /usr
RUN mkdir  /usr/local/java
#ADD 是相对路径jar,把java添加到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/

#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
 # 建立 python3.9 环境
FROM centos:7.5.1804
FROM python:3.9


MAINTAINER django:v1
 # 设置 python 环境变量
ENV PYTHONUNBUFFERED 1


# RUN apt update
# RUN apt-get install -y vim

# RUN apt-get update && RUN apt-get install -y vim

 # 设置pip源为国内源
WORKDIR ./project
COPY requirements.txt requirements.txt

# RUN pip install virtualenv -i https://pypi.douban.com/simple/
# RUN pip install virtualenvwrapper  -i https://pypi.douban.com/simple/



# 创建虚拟环境
# RUN mkvirtualenv env -p python3


 # 利用 pip 安装依赖
RUN pip install --upgrade pip -i  https://mirrors.aliyun.com/pypi/simple/
RUN pip install -r requirements.txt -i  https://mirrors.aliyun.com/pypi/simple/
# 安装uwsgi
RUN pip install uwsgi -i  https://mirrors.aliyun.com/pypi/simple/


COPY deal_bug/importexport.py /usr/local/lib/python3.9/site-packages/xadmin/plugins/importexport.py

# 暴露端口
# EXPOSE 8000
# CMD python manage_prod.py runserver 0:8000

(4)执行命令构建镜像 build

说明: jdk1.8 是镜像名  . 是当前路径
docker build -t='jdk1.8' .

注意后边的空格和点,不要省略

(5)查看镜像是否建立完成

docker images

7 Docker Compose

基本介绍

使用一个Dockerfile模板文件,可以很方便的定义一个适合自己使用的自定义镜像。但在工作中经常会碰到需要多个容器相互配合来完成某项任务或运行某个项目的情况。例如要运行一个django项目,除了django容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等,此时我们就需要使用到Docker-Compose了。

注意:

Docker-Compose仅仅用于批量操作docker容器不能用于podman的,对于podman的容器批量操作则需要安装podman-compose来批量操作。

当然,podman-compose和docker-compose的使用和语法是一样的。

Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理和编排。因此只要所操作的平台支持Docker API,就可以在其上利用Docker-Compose来进行Docker容器的编排和管理。

Docker-Compose将所管理的Docker容器分为三层,分别是工程(project),服务(service)以及容器(container)。

Docker-Compose允许我们开发者通过一个单独的docker-compose.yml配置文件(YAML 格式)来定义一组相关联的docker容器为一个工程(project)。一个工程至少有一个服务,一个服务下至少有一个容器。

Docker-Compose运行指定目录下的所有关联文件组成一个工程(工程名默认为当前目录名)。一个工程当中可包含多个服务,每个服务中可以定义Docker容器运行的镜像,参数,环境依赖等信息。

Docker-Compose的工程配置文件默认为docker-compose.yml,也可以通过-f 参数来指定成其他的配置文件名。

安装与卸载

安装环境查看

# 安装
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 查看版本
docker-compose --version


# 卸载
sudo rm /usr/local/bin/docker-compose
sudo rm /usr/bin/docker-compose

pip 安装

yum upgrade python-setuptools
yum install python-pip

pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip config set global.index-url https://mirrors.bfsu.edu.cn/pypi/web/simple
pip install --upgrade pip
pip install docker-compose

常用命令

基本命令格式

docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]

命令选项如下

-f --file FILE指定Compose模板文件,默认为当前目录下docker-compose.yml
# -p --project-name NAME 指定项目名称,默认使用当前所在目录为项目名
# --verbose  输出更多调试信息
# -v,-version 打印版本并退出
# --log-level LEVEL 定义日志等级(DEBUG, INFO, WARNING, ERROR, CRITICAL)

Usage:  docker compose [OPTIONS] COMMAND

Docker Compose

Options:
      --ansi string                Control when to print ANSI control characters ("never"|"always"|"auto") (default "auto")
      --compatibility              Run compose in backward compatibility mode
      --env-file string            Specify an alternate environment file.
  -f, --file stringArray           Compose configuration files
      --profile stringArray        Specify a profile to enable
      --project-directory string   Specify an alternate working directory
                                   (default: the path of the Compose file)
  -p, --project-name string        Project name

Commands:
  build       Build or rebuild services
  convert     Converts the compose file to platform's canonical format
  cp          Copy files/folders between a service container and the local filesystem
  create      Creates containers for a service.
  down        Stop and remove containers, networks
  events      Receive real time events from containers.
  exec        Execute a command in a running container.
  images      List images used by the created containers
  kill        Force stop service containers.
  logs        View output from containers
  ls          List running compose projects
  pause       Pause services
  port        Print the public port for a port binding.
  ps          List containers
  pull        Pull service images
  push        Push service images
  restart     Restart containers
  rm          Removes stopped service containers
  run         Run a one-off command on a service.
  start       Start services
  stop        Stop services
  top         Display the running processes
  unpause     Unpause services
  up          Create and start containers
  version     Show the Docker Compose version information

简单使用

# 创建   -  根据容器编排配置文件docker-compose.yml,进行编排和启动容器。
# 相当于`docker run`的增强版。 -d 不进入终端 -f 单个编排文件
docker-compose -f docker-compose.yaml up -d

# 删除   -  停止运行并删除docker-compose.yml配置的容器、网络、卷。
# 相当于 `docker stop` 与 `docker rm`的组合
docker-compose -f docker-compose.yml down

# 列出当前工程项目中运行容器过程中的运行日志。相当于`docker logs`
# 监控整个docker-compose.yml配置中所有的容器的运行日志,占据终端
docker-compose logs -f  

# 停止运行docker-compose.yml配置的容器,可以通过docker-compose start 再次启动
docker-compose -f docker-compose.yml stop

# 启动运行docker-compose.yml配置的容器,可以通过docker-compose start 停止
docker-compose -f docker-compose.yml start

# 重启ocker-compose.yml配置的容器,可以通过docker-compose start 停止
docker-compose -f docker-compose.yml restart

# 列出当前工程项目中的所有服务容器 -a 所有
docker-compose  ps -a

# 构建(重新构建)项目中的服务容器。
docker-compose bulid

# 删除所有(停止状态的)服务容器。
docker-compose rm

# 在指定服务上执行一个命令。
docker-compose run ubuntu ping www.baidu.com

# 执行命令
docker-compose exec

案例 一

1 安装Docker Compose

# Compose目前已经完全支持Linux、Mac OS和Windows,在我们安装Compose之前,需要先安装Docker。下面我 们以编译好的二进制包方式安装在Linux系统中。 
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 设置文件可执行权限 
chmod +x /usr/local/bin/docker-compose
# 查看版本信息 
docker-compose -version

2 卸载Docker Compose

# 二进制包方式安装的,删除二进制文件即可
rm /usr/local/bin/docker-compose

3 使用docker compose编排nginx+springboot项目

  1. 创建docker-compose目录
mkdir ~/docker-compose
cd ~/docker-compose
  1. 编写 docker-compose.yml 文件
version: '3'
services:
  nginx:
   image: nginx
   ports:
    - 80:80
   links:
    - app
   volumes:
    - ./nginx/conf.d:/etc/nginx/conf.d
  app:
    image: app
    expose:
      - "8080"
  1. 创建./nginx/conf.d目录
mkdir -p ./nginx/conf.d
  1. 在./nginx/conf.d目录下 编写spingboot.conf文件
server {
    listen 80;
    access_log off;

    location / {
        proxy_pass http://app:8080;
    }
   
}
  1. 在~/docker-compose 目录下 使用docker-compose 启动容器
docker-compose up
  1. 测试访问
http://192.168.149.135/hello

案例 二(重点看)

配置相关

项目运行及部署 | Django-Vue-Admin

# 目前我们使用的基本都是Version3版本,最新版本是3.9。
version: "3.8"
  
# 声明接下来开始配置服务容器
services:
  # 服务名,开发者自定义的,
  ubuntu1:
  	# 当前服务容器的基本依赖镜像,如果本地没有该镜像,则会自动从官网pull拉取
  	# 基于Dockerfile编译后产生的定制镜像,但得build编译好的
  	image:python3.9
  
  	# 使用build 构建Dockerfile    则基于build所在的Dockerfile编译的镜像名为image指定名字。
  	# 当前文件的Dockerfile
  	build .  
  	image: djdemo:1.0.0
  
  	# 根据上下文构建镜像
    image: mysql
  	build:
     context: /home/docker # 以是Dockerfile的文件路径,也可以是到链接到git仓库的url
     dockerfile: Dockerfile
  
   # container_name 指定当前服务容器启动以后的容器名
    container_name: "ubuntu1"
  
   # compose的command会覆盖Dockerfile里面的CMD的值。
    command: /bin/bash
  
   # 指定容器是否在操作系统重启以后,docker启动以后,是否容器也自动重启
   	restart: always
   	environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_USER=luffycity"
      - "MYSQL_PASSWORD=luffycity"
      - "MYSQL_DATABASE=luffycity"
      - "TZ=Asia/Shanghai"
   
   # networks 指定网络,可以分配容器在一个或多个网络,如果不指定,则默认分配在docker的default网络中
    networks:
      - dev
      - mysql
  
   # depends_on标签用于解决容器的依赖、启动先后顺序的问题
    depends_on:
      - mysql
      - redis
  
    # ports用于映射端口的标签。
    # 使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。相当于docker -p
  	ports:
	  - "3000"  # 等价于 "3000:3000"
      - "8000:8000"
      - "49100:22"

    volumes:
 	# 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  	# 相当于 /var/lib/mysql:/var/lib/mysql
  	   - /var/lib/mysql
    # 使用绝对路径挂载数据卷
       - /opt/data:/var/lib/mysql
    # 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
       - ./cache:/tmp/cache
    # 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
       - ~/configs:/etc/configs/:ro
    # 已经存在的命名的数据卷。
       - datavolume:/var/lib/mysql
   
    # 如果不使用宿主机的路径,可以指定一个volume_driver。
    volume_driver: mydriver
  
    # 从另一个服务或容器挂载其数据卷:
    volumes_from:
   	   - service_name   
          - container_name
  
    # 自定义DNS服务器。可以是一个值,也可以是一个列表。
    dns:8.8.8.8
	dns:
    - 8.8.8.8   
      - 9.9.9.9
  
   # 暴露端口,但不映射到宿主机,只允许能被连接的服务访问。仅可以指定内部端口为参数
   expose:
    - "3000"
    - "8000"
  
   # 链接到其它服务中的容器。使用服务名称(同时作为别名),或者“服务名称:服务别名”(如 SERVICE:ALIAS)
   links:
    - db
    - db:database
    - redis
   
   
  
  # redis服务
  redis:
    image: redis:6.0
  # mysql服务
  mysql:
    image: mysql:8.0.26
  
  # 设置网络模式。
  net: "bridge"
  net: "none"
  net: "host"
  
   
  
  
  

# 网络配置
networks:
  # 指定网络名称,相当于网卡名
  dev:
    # driver 网卡驱动:bridge 桥接模式,网卡驱动有三种模式:bridge、host、none
    # 查看网络:docker network ls
    driver: bridge
  pro:
    driver: bridge
  
  
 

yaml编写

version: "3"
services:
  dvadmin-web:
    container_name: dvadmin-web
    ports:
      - "8080:8080"
    build:
      context: ./
      dockerfile: ./docker_env/web/Dockerfile
    environment:
      TZ: Asia/Shanghai
    volumes:
      - ./docker_env/nginx/my.conf:/etc/nginx/conf.d/my.conf
    expose:
      - "8080"
    networks:
      network:
        ipv4_address: 177.8.0.11

  dvadmin-django:
    build:
      context: .
      dockerfile: ./docker_env/django/Dockerfile
    container_name: dvadmin-django
    working_dir: /backend
# 打开mysql 时,打开此选项
#    depends_on:
#      - dvadmin-mysql
    environment:
      PYTHONUNBUFFERED: 1
      DATABASE_HOST: dvadmin-mysql
      TZ: Asia/Shanghai
    volumes:
      - ./backend:/backend
      - ./logs/log:/var/log
    ports:
      - "8000:8000"
    expose:
      - "8000"
    restart: always
    networks:
      network:
        ipv4_address: 177.8.0.12

#  dvadmin-mysql:
#    image: mysql:5.7
#    container_name: dvadmin-mysql
#    #使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限
#    #设置为true,不然数据卷可能挂载不了,启动不起
##    privileged: true
#    restart: always
#    ports:
#      - "3306:3306"
#    environment:
#      MYSQL_ROOT_PASSWORD: "123456"
#      MYSQL_DATABASE: "dvadmin_pro"
#      TZ: Asia/Shanghai
#    command:
#      --wait_timeout=31536000
#      --interactive_timeout=31536000
#      --max_connections=1000
#      --default-authentication-plugin=mysql_native_password
#    volumes:
#      - "./docker_env/mysql/data:/var/lib/mysql"
#      - "./docker_env/mysql/conf.d:/etc/mysql/conf.d"
#      - "./docker_env/mysql/logs:/logs"
#    networks:
#      network:
#        ipv4_address: 177.8.0.13


# 如果使用celery 插件,请自行打开此注释
#  dvadmin-celery:
#    build:
#      context: .
#      dockerfile: ./docker_env/celery/Dockerfile
#    # image: django:2.2
#    container_name: dvadmin-celery
#    working_dir: /backend
#    depends_on:
#      - dvadmin-mysql
#    environment:
#      PYTHONUNBUFFERED: 1
#      DATABASE_HOST: dvadmin-mysql
#      TZ: Asia/Shanghai
#    volumes:
#      - ./backend:/backend
#      - ./logs/log:/var/log
#    restart: always
#    networks:
#      network:
#        ipv4_address: 177.8.0.14


# dvadmin-redis:
#   image: redis:6.2.6-alpine # 指定服务镜像,最好是与之前下载的redis配置文件保持一致
#   container_name: dvadmin-redis # 容器名称
#   restart: on-failure # 重启方式
#   environment:
#     - TZ=Asia/Shanghai # 设置时区
#   volumes: # 配置数据卷
#     - ./docker_env/redis/data:/data
#     - ./docker_env/redis/redis.conf:/etc/redis/redis.conf
#   ports: # 映射端口
#     - "6379:6379"
#   sysctls: # 设置容器中的内核参数
#     - net.core.somaxconn=1024
#   command: /bin/sh -c "echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf && redis-server /etc/redis/redis.conf --appendonly yes" # 指定配置文件并开启持久化
#   privileged: true # 使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限
#   networks:
#     network:
#       ipv4_address: 177.8.0.15


networks:
  network:
    ipam:
      driver: default
      config:
        - subnet: '177.8.0.0/16'

dockerfile编写

FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/node12-base-web:latest
WORKDIR /web/
COPY web/. .
RUN npm install --registry=https://registry.npm.taobao.org
RUN npm run build

FROM nginx:alpine
COPY ./docker_env/nginx/my.conf /etc/nginx/conf.d/my.conf
COPY --from=0 /web/dist /usr/share/nginx/html

FROM node:14-alpine
WORKDIR /web/
COPY ./web/package.json .
RUN npm install --registry=https://registry.npm.taobao.org

常用命令

# 使用docker-compose启动四个容器
docker-compose up

# 如果前端代码有更新,可以使用此命令重新打包镜像
docker-compose build dvadmin-web

# 使用docker-compose 后台启动
docker-compose up -d

# 服务都启动成功后,使用此命令行可清除none镜像
docker system prune

# 查询容器运行日志
前端日志:  docker logs dvadmin-web -f --tail 100
后端日志:  docker logs dvadmin-django -f --tail 100

8 Docker私有仓库

参考: https://www.jianshu.com/p/b93feaf43f37

8.1 私有仓库搭建与配置

(1)拉取私有仓库镜像

docker pull registry

(2)启动私有仓库容器

docker run -di --name=registry  \
  --restart=always  \
  -v /usr/local/registry:/var/lib/registry \
  -p 5001:5000\
  registry

(3)打开浏览器 输入地址http://192.168.184.141:5000/v2/_catalog看到 {"repositories":[]} 表示私有仓库搭建成功并且内容为空

(4)修改daemon.json

vi /etc/docker/daemon.json

添加以下内容,保存退出。

{"insecure-registries":["192.168.184.141:5000"]} 

如下所示
{
  "registry-mirrors": [
  	#"https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    #"https://mirror.baidubce.com"],
  #"insecure-registries":["192.168.184.141:5000"] 
}

此步用于让 docker信任私有仓库地址

(5)重启docker 服务

systemctl restart docker

8.2 镜像上传至私有仓库

(1)标记此镜像为私有仓库的镜像

docker tag jdk1.8 192.168.184.141:5000/jdk1.8

(2)再次启动私服容器

docker start registry

(3)上传标记的镜像

docker push 192.168.184.141:5000/jdk1.8

8.3 镜像的删除

(1)找到本地映射的位置

cd /usr/local/registry/docker/registry/v2/repositories
删除文件
rm  -r  ./XXX 
posted @ 2023-05-29 16:52  派森的猫  阅读(105)  评论(0编辑  收藏  举报