Life, half is memory, half is to continue.
Docker 的用法整理
By Vincent. @2022.10.25
Docker 的用法整理

【docker 简介】

一、什么是docker

官方地址:https://docs.docker.com/

Docker 是一个基于go语言开发的开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

二、docker核心概念

docker三大核心概念:镜像 Image、容器 Container、仓库 Repository

docker面向对象
容器对象
镜像

三、docker架构及原理

概念说明
Docker 镜像(Images)Docker 镜像是用于创建 Docker 容器的模板。基于镜像可以创建容器,同一个镜像可以创建多个容器;
Docker 容器(Container)容器是独立运行的一个或一组应用,是镜像运行时的实体。
Docker 客户端(Client)Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。
Docker 主机(Host)一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
Docker RegistryDocker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。镜像仓库分为公共镜像仓库Docker Hub和一些私有化部署的仓库比如:Harbor(这两种类似于github和gitlab)Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker MachineDocker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。

四、docker轻量级的实现原理

docker容器本质上是宿主机的进程,Docker通过namespace实现了资源隔离,通过cgroups实现了资源限制,通过写时复制机制(copy-on-write)实现了高效的文件操作。

namespace资源隔离

linux内核提拱了6种namespace隔离的系统调用:

namespace系统调用参数隔离内容
UTSCLONE_NEWUTS主机名或域名 (since Linux 2.6.19)
IPCCLONE_NEWIPC信号量、消息队列和共享内存(since Linux 2.6.19)
PIDCLONE_NEWPID进程编号(since Linux 2.6.24)
NetworkCLONE_NEWNET网络设备、栈、端口等(since Linux 2.6.24)
MountCLONE_NEWNS挂载点(文件系统)(since Linux 2.6.24)
UserCLONE_NEWUSER用户组和用户组(started in Linux 2.6.23 and completed in Linux 3.8)

五、docker的优缺点

1.优点

2.缺点

【docker 安装与启动】

一、docker安装与启动

1.安装docker的几种方式

1)安装最新版本docker

① 先卸载旧版本的docker

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

② 指定Docker下载源(可选,适用于首次安装)

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

③ 安装Docker(默认安装最新版本)

yum install -y docker-ce docker-ce-cli containerd.io

④ 验证是否安装成功

docker version

2)安装指定版本的docker

yum list docker-ce --showduplicates | sort -r  # 查看所有可用版本
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io  # 安装指定版本

3)通过脚本一键安装docker

脚本内容如下:

#!/bin/bash
echo "set default docker install repo"
yum install -y yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
echo "install docker ..."
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker
systemctl status docker

2.启动docker

systemctl start docker  # 启动服务
systemctl status docker  # 查看状态
systemctl stop docker  # 停止服务
systemctl restart docker  # 重启服务

二、创建第一个docker容器

1.创建容器

按照国际惯例,先运行一个hello-world的容器

docker run hello-world

# 如果网络等一切正常的话,会出现如下提示,表示容器已经创建成功
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete 
Digest: sha256:18a657d0cc1c7d0678a3fbea8b7eb4918bba25968d3e1b0adebfa71caddbc346
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

2.查看容器

docker ps -a  # 查看所有容器

# 创建成功,容器列表中就会有hello-world的容器,但名字不是hello-world,因为我们在运行容器时并未指定名称
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
a07f1a8ea1a4   hello-world   "/hello"   21 seconds ago   Exited (0) 20 seconds ago             adoring_chatterjee

三、卸载docker

1.常规方式卸载

① 停止docker服务

systemctl stop docker

② 搜索已经安装的docker安装包

yum list installed | grep docker
rpm -qa | grep docker
yum -y remove docker-ce.x86_64 
yum -y remove docker-ce-cli.x86_64 
yum -y remove containerd.io.x86_64

③ 移除所有相关安装包

yum -y remove contained.io.x86_64

④ 删除docker镜像及相关文件夹

rm -rf /var/lib/docker

2.脚本卸载

所谓的使用脚本安装和卸载,通俗理解就是把上述多个操作步骤的命令放在一个脚本中批量执行,内容如下:

#!/bin/bash
systemctl stop docker
yum -y remove docker-ce.x86_64
yum -y remove docker-ce-cli.x86_64
yum -y remove containerd.io.x86_64
rm -rf /var/lib/docker
rm -rf /etc/docker/daemon.json

【docker 常用操作命令】

一、镜像操作命令

命令说明
pull拉取镜像
search搜索相关镜像
tag重命名镜像
rmi删除镜像
images 或 image ls查看所有镜像
build基于Dockerfile构建镜像
commit基于已有容器构建镜像

1.拉取镜像

使用”docker pull 镜像名称”,拉取远程仓库的镜像到本地(先校验本地是否存在,本地不存在时再默认从官网拉取最新版本的镜像)

以busybox为例:

BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Linux 系统的自带的shell。

docker pull busybox  # 拉取镜像

在拉取镜像前,也可以通过docker search命令搜索不同类型的镜像

docker search busybox  # 搜索相关镜像

2.查看镜像

使用 “docker image ls” 或 “docker images” 命令查看本地已经存在的镜像

docker images  # 查看所有镜像
docker images | grep busybox  # 查看指定镜像

3.修改镜像名称

使用 “docker tag 原始镜像名称 新名称” 命令重命名镜像,如:docker tag busybox:latest mybusybox:V1.0,重命名镜像会新增一条镜像,相当于创建了一个副本,但ID相同。

docker tag busybox:latest mybusybox:V1.0

4.删除镜像

使用 “docker rmi 镜像名称” 命令删除无用镜像,通过镜像名称删除,只会删除指定名称的镜像;通过镜像ID删除,会删除所有ID相同的镜像。

docker rmi mybusybox:V1.0
docker rmi -f ff4a8eb070e1

二、容器操作命令

容器操作命令:

命令说明
create创建容器
run运行容器,run = pull + create + start
exec…-it…sh进入容器内部
start启动容器
restart重启容器
stop停止容器
rm删除容器
commit基于已有容器构建镜像
ps查看容器状态:docker ps -a:查看所有容器docker ps -l:查看最近操作的容器
logs查看容器日志:docker logs 容器名:查看指定容器的运行日志docker logs -f 容器名:实时查看指定容器的运行日志

容器操作相关参数:

命令说明
–name指定容器名称:–name=容器名–name 容器名
-d后台运行
-p映射端口,宿主机端口:容器端口,例如:-p 3307:3306
-v挂载目录到本地,宿主机目录:容器目录,例如:-v /usr/local/nginx:/usr/local/nginx
–restart自动重启,例如:–restart=always,跟随docker服务的重启而重启

1.创建容器

docker create (–name=容器名) 镜像名,例如:

docker create --name=mybusybox busybox

2.查看容器状态

docker ps -a  # 查看所有容器
docker ps -a | grep mybusybox  # 过滤查看指定容器
docker ps -l  # 查看最近操作的容器

通过create命令创建完成后的容器是”Created”状态的,可以通过start命令来启动容器

3.启动容器

docker start mybusybox

4.进入容器

通过”docker exec -it 容器名 sh”命令进入容器内部,例如:

docker exec -it mybusybox sh

5.运行容器

docker run = docker pull + docker create + docker start

docker run --name=mynginx -d -p 81:80 nginx

6.停止容器

docker stop 容器名或容器ID,例如:

docker stop mybusybox
docker stop 6fbf5a7a580b

7.删除容器

docker rm 容器名或容器ID,删除前要先停止容器,例如:

docker stop mybusybox
docker rm mybusybox
docker rm 6fbf5a7a580b

8.查看容器日志

例如:

docker logs sonic_sonic-server-controller_1
docker logs -f sonic_sonic-server-controller_1

9.基于已有容器构建为新的镜像模板

用法:docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

OPTIONS释义
-a标注作者信息
-c使用Dockerfile指令来生成镜像
-m提交说明信息,类似于git commit -m “xxxx”
-p在提交时,暂停容器

例如:当前有个需求,将当前服务器上正在运行的一个容器,无痕迁移到另一台服务器上运行。意味着需要执行以下步骤:

将当前正在运行的容器构建为新的镜像A>>将新镜像A的镜像文件复制到另一台服务器或直接将镜像A提交到镜像仓库>>在另一台服务器上将镜像A从镜像仓库下载下来>>基于镜像A创建容器并运行

① 打包容器

为了便于演示,先将一个文件复制到已有容器内

docker cp jdk_install.sh mysql:/home

② 查看容器内文件

docker exec -it mysql sh

可以看到,已经将jdk_install.sh文件复制到了mysql容器的/home目录下:

③ 基于容器构建新的镜像

docker commit -a "chenjigang" mysql new-mysql

通过”docker images”命令查看当前镜像列表,可以看到名为new-mysql的镜像:

④ 基于新镜像运行容器

docker run -d --name new-mysql-container -e MYSQL_ROOT_PASSWORD=123456 -p 3308:3306 new-mysql

⑤ 查看容器内文件

docker exec -it new-mysql-container sh

通过下图可以看出,之前复制到容器内的jdk_install.sh文件,已经保存到镜像中、并跟随出现在新的容器内:

【docker 使用技巧】

一、更换镜像源

1.配置文件路径:/etc/docker/daemon.json,若不存在则新建此文件

{
        "registry-mirrors":[
        "http://registry.docker-cn.com",
        "http://docker.mirrors.ustc.edu.cn",
        "http://hub-mirror.c.163.com",
        "http://cr.console.aliyun.com/",
        "https://8wb4g36l.mirror.aliyuncs.com"
]
}

2.配置完成后重启docker服务

systemctl restart docker.service

二、更换存储目录

docker安装完成后,默认存储路径为/var/lib/docker。创建容器后,每个容器的数据卷容量上限与/var/lib/docker所在的挂载的磁盘大小有关。例如下图所示:挂载的磁盘大小为50GB,则docker容器数据卷上限就是50GB,如果有多个容器,则这些容器共享50GB的容量,而且同时也与挂载磁盘下的其他目录共享使用。那么如果运行的容器数量较多,或是遇到需要存储大量数据如gitlab这类容器,50G显然就有些捉襟见肘。此时可以通过修改docker存储路径的方式扩容容器的容量上限。特别提一句,docker存储路径最好尽早修改,这样可以避免后期因磁盘写满导致的各种容器运行异常问题。

三种方式修改docker存储路径,分别为:

1.方式一:修改docker配置文件

编辑docker配置文件

vi /usr/lib/systemd/system/docker.service

使用”–graph”或”-g”参数指定存储位置

ExecStart=/usr/bin/dockerd --graph /home/docker_home

修改完成后重新加载配置文件并重启docker服务

// reload配置文件 
systemctl daemon-reload 
 
// 重启docker
systemctl restart docker.service

2.方式二:创建daemon.json文件

docker1.12或以上版本,可以创建或修改daemon.json文件来指定存储位置。docker查看版本命令“docker version”

vi /etc/docker/daemon.json

在最后添加graph字段,定义docker目录

{
        "registry-mirrors":[
        "http://registry.docker-cn.com",
        "http://docker.mirrors.ustc.edu.cn",
        "http://hub-mirror.c.163.com",
        "http://cr.console.aliyun.com/",
        "https://8wb4g36l.mirror.aliyuncs.com"
],
        "graph": "/home/docker_home"
}

修改完成后同样需要重新加载配置文件、重启docker服务

systemctl daemon-reload
systemctl restart docker.service

3.方式三:创建软链接(推荐)

前两种方式适用于首次安装docker后没有pull过镜像、创建过容器。即使修改了存储路径,因为没有镜像和容器,所以也不会产生任何影响。

创建软链接的方式,适用于已经创建过容器、并且容器已经产生数据的情况。这种方式可以避免对镜像及现有容器数据造成破坏,以及更改存储路径后找不到数据的情况。具体步骤如下:

① 查看docker路径

默认情况下Docker的存放位置为:/var/lib/docker,也可以通过如下命令查看docker存储路径

docker info | grep "Docker Root Dir"

② 停掉docker服务

systemctl stop docker

③ 移动docker目录

mv /var/lib/docker /home/docker_home

③ 创建软链接

ln -s /home/docker_home /var/lib/docker

④ 启动docker服务

systemctl start docker

修改完成后,我们可以通过以下命令查看docker的存储目录:

docker info | grep "Root Dir"  
# 修改成功会返回以下内容:
# Docker Root Dir: /home/docker_home

查看/var/lib/目录,docker目录是一个软链接,指向/home/docker_home,配置正确。

三、修改时区

1.创建容器时设置时区

创建时增加映射使用主机时区

-v /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime

2.创建容器后修改时区

① 查看宿主机时区

通过date -R命令可以看出,宿主机的时区为东八区,查看/etc/localtime,可以看出localtime实际上是一个软链接,背后指向的是/usr/share/zoneinfo/Asia/Shanghai

[root@test_host home]# date -R
Thu, 08 Sep 2022 11:05:37 +0800
[root@test_host home]# ls -l /etc/localtime
lrwxrwxrwx. 1 root root 35 8月  29 17:17 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

② 拷贝本地时区到docker容器内部

docker cp /usr/share/zoneinfo/Asia/Shanghai docker.ui:/etc/localtime

③ 进入容器内部查看时区

docker exec -it docker.ui sh  # 进入docker.ui容器
ls /etc  # 查看/etc下是否存在已经复制的localtime文件
date -R  # 查看时区

通过下图可以看出,/etc下已经存在了宿主机复制过来的localtime文件,时区为东八区,已经修正。

四、拷贝文件

主要用到”docker cp”命令

1.从宿主机拷贝到容器

docker cp 宿主机文件路径 容器名:目录,例如:

docker cp redis_log mysql:/home

2.从容器内拷贝到宿主机

docker cp 容器名:文件路径 宿主机目录,例如:

docker cp mysql:/home/mayfly-go.sql /home/

五、常见问题解决

1.容器报错ipv4网络不可用

运行容器时报错

如果是容器运行直接报这个错, 解决方式:
① 在宿主机上执行

echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf  

② 重启network和docker服务

systemctl restart network
systemctl restart docker

创建容器时报错

“WARNING: IPv4 forwarding is disabled. Networking will not work.”

如果是运行镜像、创建容器的时候报这个错,则直接重启docker服务:

systemctl restart docker

【docker 一键快速搭建环境】

1.docker一键搭建Jenkins

# 拉取镜像
docker pull jenkins
# 运行容器
docker run -d --name=jenkins -v /home/jenkins:/var/jenkins_home -p 8088:8080 -u root --restart=always jenkins

前台访问:http://192.168.1.122:8088/

注意:首次访问需输入密码,宿主机上密码文件路径为 /home/jenkins/secrets/initialAdminPassword,或是进入容器内查看:/var/jenkins_home/secrets/initialAdminPassword

初始化完成后,原始密码文件自动删除:

2.docker一键搭建Gitlab

# 拉取镜像
docker pull gitlab/gitlab-ce
# 创建gitlab环境变量
export GITLAB_HOME=/home/gitlab
# 运行容器
docker run -d --name=gitlab -u root --restart=always -v $GITLAB_HOME/config:/etc/gitlab -v $GITLAB_HOME/logs:/var/log/gitlab -v $GITLAB_HOME/data:/var/opt/gitlab -p 443:443 -p 8081:80 -p 2222:22 gitlab/gitlab-ce

http://192.168.1.122:8081/ 首次访问会提示修改密码,用户名为 root

3.docker一键搭建Nginx

官网地址:https://hub.docker.com/_/mysql

# 拉取镜像
docker pull nginx
# 运行容器
docker run -d --name mynginx -p 81:80 nginx

浏览器端访问:http://192.168.1.123:81/

4.docker一键搭建MySQL

官网地址:https://hub.docker.com/_/mysql

# 拉取镜像
docker pull mysql
# 运行容器
docker run -d -e MYSQL_ROOT_PASSWORD=123456 --name=mymysql -p 3307:3306 mysql
# 进入mysql容器
docker exec -it mysql sh
# 登录mysql
mysql -uroot -p123456

mysql命令行操作

使用工具连接mysql数据库

5.一键搭建RabbitMQ

# 拉取镜像
docker pull rabbitmq:3.7-management
# 启动容器
docker run --name=rabbitmq -d --restart always -p 15672:15672 -p 5672:5672 -v /home/rabbitmq:/var/lib/rabbitmq rabbitmq:3.7-management

注:如果docker pull rabbitmq后面不带management,启动rabbitmq后是无法打开管理界面的,所以我们需要下载带management插件的rabbitmq

浏览器端访问:http://192.168.1.123:15672/,登录账号和密码都是:guest

【dockerfile 定制镜像】

一、Dockerfile是什么?

1.简介

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

2.作用

Dockerfile的作用:定制镜像,所谓定制镜像,就是以一个镜像为基础,在其上进行定制,丰富功能、提前作一些配置等。

二、Dockerfile常用指令

1.常用指令释义

指令说明
FROM指定基础镜像
MAINTAINER增加说明信息,如维护者姓名邮箱等,非必须
RUN执行具体的linux命令(用于构建镜像时执行相关的命令)
USER基于哪个用户运行容器
ADD将本地的文件添加到镜像内(支持正则表达式拷贝,支持更多的文件类型的拷贝,如网络文件的下载后拷贝,ADD http://xxxx/test.tar.gz /test/)
COPY将本地文件拷贝到镜像内(只支持基本的文件、文件夹的拷贝,推荐使用COPY),最好将要拷贝的文件置于Dockerfile同一目录下
WORKDIR目录切换指令,类似于linux的cd命令WORKDIR /home/jenkins_home/conf 等同于以下指令:WORKDIR /homeWORKDIR jenkins_home/conf
EXPOSE指定容器监听的端口,仅作为说明,不会真正生效,还是需要使用docker run -p参数进行端口映射
CMD类似于RUN指令,区别与CMD是在启动容器时执行相关的命令,CMD echo “hello world” 或 [‘ECHO’,’hello world’]都可以,推荐使用后者列表形式
ENTRYPOINT指定ENTRYPOINT参数后,使用docker run xxxx 启动容器时,docker run 后面的参数不会被覆盖
ENV指定运行容器时的环境变量,格式为 KEY=VALUE或KEY VALUE,如ENV VERSION=2.0在后续指令中可以使用$VERSION进行替换2.0
VOLUME数据栈声明,做匿名挂载用,假设指令为VOLUME /usr/local,则在启动容器后会在服务器上docker默认路径/var/lib/docker/volumes/下自动生成一个文件夹,用于挂载/usr/local,常用于执行docker run命令时忘记指定-v 参数,从而自动保存一些重要的数据时使用

2.’CMD’、’ENTERPOINT’、’docker run xxx’ 三者之间的区别与联系

总结:CMD相对更为灵活,用户可以通过docker run 更改dockerfile中CMD的指令,而ENTRYPOINT则更为单一,使用docker run命令行参数启动容器时无法修改dockerfile中ENTRYPOINT的指令;

3.Dockerfile示例

自定义Dockerfile

如下,我们制作一个简单的Dockerfile用来构建镜像,它是基于centos7镜像。其中,执行一些简单的命令,如输出信息、创建文件夹,另外提前添加文件到镜像目录、切换目录,最后安装一个工具,执行查看网卡命令:

# 基于centos7镜像
FROM centos:7

# 维护者信息
MAINTAINER "chenjigang"

# 基于root用户运行容器
USER root

# 运行命令
RUN echo "test dockerfile..."
RUN mkdir -p /home/docker_home

# 本地复制文件到镜像内
COPY docker_install.sh /home/docker_home/docker_install.sh

# 切换目录
WORKDIR /home/docker_home
RUN ls -al

RUN yum install -y net-tools
RUN ifconfig

mysql示例

下图是MySQL的官方镜像的dockerfile,也是用到了上面介绍的各个命令,将其有机地结合,例如:一开始会添加一个文件>>然后运行bash>>创建用户和用户组>>中间设置环境>>设置数据目录>>最后启动mysqld,从而实现MySQL的构建:

三、从Dockerfile构建镜像

Dockerfile 创建完成后,可以使用 docker build 命令根据 Dockerfile 构建一个镜像。Docker build常用的指令包括两个参数:

基于上面第一个Dockerfile提交构建:

# 运行当前目录下的Dockerfile文件,生成一个名为mycentos7的镜像
docker build -t mycentos7 .

如下图所示,运行docker build构建镜像命令后,正在按照上述自定义的Dockerfile中的步骤顺序执行:

从下图可以看出,已经成功构建了一个镜像:mycentos7:latest

查看镜像列表,存在新构建的镜像mycentos7:

基于mycentos7镜像创建一个容器:

docker run -it --name mycentos7 mycentos7:latest sh

此时,启动容器,进入镜像shell环境内会发现Dockerfile文件中定义的命令已生效:

四、Dockerfile构建镜像原理

https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

每多一行命令,镜像就会多一层

【docker-compose 容器编排】

一、Docker-Compose介绍

1.简介

Docker-Compose项目是Docker官方的开源项目,负责实现对Docker多容器编排管理系统。使用 Docker-compose,可以用一个 YAML 文件定义一组要启动的容器,以及容器运行时的属性。 Docker-Compose的工程配置文件默认为docker-compose.yml

项目地址:https://github.com/docker/compose

2.Docker-Compose前世今生

Docker Compose 的前身是 Fig,现阶段 Docker Compose 是 Docker 官方的单机多容器管理系统(不能跨机器),它本质是一个Python 脚本,它通过解析用户编写的 yaml 文件,调用 Docker API 实现动态的创建和管理多个容器。

二、Docker-Compose安装

1.使用curl命令安装(推荐)

# 下载 Docker Compose 的安装包
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 修改 Docker Compose 执行权限
sudo chmod +x /usr/local/bin/docker-compose

2.使用PIP安装

需提前安装Python环境

pip install -U docker-compose

三、Docker-Compose常用指令组成

Docker Compose 文件主要分为三部分: services(服务)、networks(网络) 和 volumes(数据卷)

1.常用指令说明

指令说明
image镜像名称,基于哪个镜像,使用现有的镜像
build使用自定义的镜像,若当前docker-compose.yml和Dockerfile在同一路径下,则build的键值用 . 也可以,若不在同一路径下,或Dockerfile文件不是用的默认名称Dockerfile,则需指定Dockerfile的路径
command启动镜像时用的命令,类似于Dockerfile中的CMD指令
container_name容器名称
depends_on指定服务启动顺序,如存在多个服务nginx、db、Jenkins时,则在Jenkins服务下定义depends_on: db,会优先启动db服务
links解决容器之间的链接,使用db可以链接到db服务,使用别名test_db也可以
ports指定端口,端口映射时使用,类似于docker命令中的-p参数
volumes数据挂载时使用,类似于docker命令中的-v参数

2.docker-compose.yml示例

支持四种命名格式:docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml

sonic私有云真机平台:http://192.168.1.20:3000/Index/Devices

下面就以前面分享过的《开源云真机平台-Sonic应用实践》中的sonic服务的docker-compose.yml为例,一起来看看上述指令的用法:

version: '3'  # 版本
services:  # 服务,
  sonic-server-eureka:  # 容器名(sonic微服务注册中心)
    image: "registry.cn-hangzhou.aliyuncs.com/sonic-cloud/sonic-server-eureka:v1.5.0-release"
    hostname: sonic-server-eureka
    environment:  # 环境,读取配置文件中eureka的用户名密码等
      - SONIC_EUREKA_USERNAME
      - SONIC_EUREKA_PASSWORD
      - SONIC_EUREKA_PORT
      - SONIC_EUREKA_HOST=sonic-server-eureka
    volumes:  # 目录映射
      - ./logs/:/logs/
    networks:  # 网络名
      - sonic-network
    ports:  # 端口映射
      - "${SONIC_EUREKA_PORT}:${SONIC_EUREKA_PORT}"
  sonic-server-gateway:  # 容器名(sonic微服务网关)
    image: "registry.cn-hangzhou.aliyuncs.com/sonic-cloud/sonic-server-gateway:v1.5.0-release"
    hostname: sonic-server-gateway
    environment:  # 同样也是一些环境配置,用于和eureka容器通信
      - SONIC_EUREKA_USERNAME
      - SONIC_EUREKA_PASSWORD
      - SONIC_EUREKA_PORT
      - SONIC_EUREKA_HOST=sonic-server-eureka
      - SECRET_KEY
      - EXPIRE_DAY
    volumes:
      - ./logs/:/logs/
    depends_on:  # 指定服务启动顺序,先启动sonic-server-eureka容器
      - sonic-server-eureka
    networks:  # 网络,各个容器必须处于同一网络下才能相互通信
      - sonic-network
    restart: on-failure
  sonic-server-controller:  # 容器名
    image: "registry.cn-hangzhou.aliyuncs.com/sonic-cloud/sonic-server-controller:v1.5.0-release"
    environment:  # 环境配置,读取数据库、账号等配置
      - SONIC_EUREKA_USERNAME
      - SONIC_EUREKA_PASSWORD
      - SONIC_EUREKA_PORT
      - SONIC_EUREKA_HOST=sonic-server-eureka
      - MYSQL_HOST
      - MYSQL_PORT
      - MYSQL_DATABASE
      - MYSQL_USERNAME
      - MYSQL_PASSWORD
      - SONIC_SERVER_HOST
      - SONIC_SERVER_PORT
      - SECRET_KEY
      - EXPIRE_DAY
      - REGISTER_ENABLE
      - NORMAL_USER_ENABLE
      - LDAP_USER_ENABLE
      - LDAP_USER_ID
      - LDAP_BASE_DN
      - LDAP_BASE
      - LDAP_USERNAME
      - LDAP_PASSWORD
      - LDAP_URL
    networks:
      - sonic-network
    volumes:
      - ./logs/:/logs/
    depends_on:
      - sonic-server-eureka
    restart: on-failure
  sonic-server-folder:
    image: "registry.cn-hangzhou.aliyuncs.com/sonic-cloud/sonic-server-folder:v1.5.0-release"
    environment:
      - SONIC_EUREKA_USERNAME

通过上述配置我们能够发现,docker-compose.yml这个配置文件,就是由前面我们介绍的一个个指令按照一定的格式、顺序、规则进行排列、相结合组成,从而实现不同容器的排编,相互通信,进而实现强大的功能。

四、Docker-Compose操作命令

用法:
Define and run multi-container applications with Docker.

Usage:
docker-compose [-f <arg>…] [–profile <name>…] [options] [–] [COMMAND] [ARGS…]
docker-compose -h|–help

1.docker-compose操作命令

官方所有指令

常用指令

指令说明
up启动容器编排(前提是当前目录存在docker-compose.yml文件)
down删除容器编排,适用于docker-compose.yml文件发生变更、或安装出错时的卸载重装
ps查看所有服务状态,类似于docker ps -a
start启动服务
stop指定服务启动顺序,如存在多个服务nginx、db、Jenkins时,则在Jenkins服务下定义depends_on: db,会优先启动db服务
logs查看docker-compose操作日志

2.docker-compose操作参数

官方所有选项

常用选项

参数说明
-f指定yml文件启动,当前目录下不存在docker-compose.yml文件时使用
-d后台运行

3.容器编排操作实践

启动容器编排

docker-compose up # 启动容器(前提是当前目录存在docker-compose.yml文件)
docker-compose -f docker-compose.yml up -d  # 指定yml文件启动并设置后台运行

启动容器编排:创建网络>>创建并运行各个容器>>各个容器之间建立连接

在使用”docker-compose up”和”docker-compose down”命令时,若当前目录下不存在以下四种中的任一格式文件:docker-compose.yml, docker-compose.yaml, compose.yml, compose.yaml,或也未使用-f参数指定其他文件时,会报错提示:

删除容器编排

docker-compose down

删除容器编排:停止各个容器>>移除各个容器>>删除容器创建的网络

查看容器状态

docker-compose ps  # 查看所有服务状态,类似于docker ps -a

启动服务

# docker-compose start  启动所有服务
# docker-compose start [SERVICE...]    启动指定服务
docker-compose start

停止服务

# docker-compose stop    停止所有服务
# docker-compose stop [options] [SERVICE...]    停止指定服务
docker-compose stop

与down命令不同,stop只会停止相关容器,但不会删除相关容器

查看日志

docker-compose logs

五、利用Docker Compose搭建wordpress博客系统

前面对一些常用指令作了说明,以及通过sonic前后台服务的docker-compose.yml案例对容器编排作了简单介绍,下面我们结合一个docker-compose搭建WordPress的案例来搭建我们自己的容器编排服务,官方配置文件内容如下:

1.配置docker-compose.yml

官网地址:https://docs.docker.com/compose/wordpress/

services:
  db:
    # We use a mariadb image which supports both amd64 & arm64 architecture
    image: mariadb:10.6.4-focal
    # If you really want to use MySQL, uncomment the following line
    #image: mysql:8.0.27
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=somewordpress
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
    expose:
      - 3306
      - 33060
  wordpress:
    image: wordpress:latest
    volumes:
      - wp_data:/var/www/html
    ports:
      - 88:80
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
volumes:
  db_data:
  wp_data:

【注意】

2.查看容器状态

docker-compose ps -a

3.前端访问

启动docker-compose,各个容器处于up状态,此时就可以访问前端页面,http://192.168.1.123:88/,会先进行安装配置,如:设置数据库、站点取名

个人博客主页如下:

因为我是内网服务器,只能在局域网内访问,公网无法访问。如果你有一台带有公网的云服务器,如阿里云,那么妥妥的就可以搭建自己的个人网站了,这种对服务器要求不高,入门级的就可以。现在的云服务器都挺便宜,一年才几十块钱,像阿里云服务器个人用户可以免费体验一个月。关于WordPress详细搭建方法可以参考我前面介绍的《用2核2G的入门级云服务器搭建WordPress博客系统

【docker 镜像仓库】

在前面的文章中,我们介绍了如何定制镜像、容器编排,但仿佛对镜像管理并没有提及,那么镜像文件我们是否可以像管理代码一样实现push、pull的操作呢?答案是有的,docker-hub就是一款公共仓库,在上面可以搜索到别人创建好的各种各样的镜像,以及管理自己的镜像;Harbor是一款私有化镜像仓库,我们可以把镜像上传上去,同一内网下的其他用户均可以下载使用,因为是部署在自己的服务器,因此对于安全性这方面更有保障。docker-hub和Harbor的关系我们可以类比成GitHub和Gitlab。

一、公共镜像仓库Docker-hub

1.docker-hub简介

公共镜像仓库一般是 Docker 官方或者其他第三方组织(阿里云,腾讯云,网易云等)提供的,允许所有人注册和使用的镜像仓库。Docker Hub 是全球最大的镜像市场,目前已经有超过 10w 个容器镜像。

2.提交镜像到仓库

具体步骤:注册账号>>登录>>创建仓库>>>linux命令行docker登录>>修改镜像名称(保持与仓库名称一致)>>提交镜像到仓库

① 创建镜像仓库

类似于github上创建代码仓库,分为public(公开的,互联网可见)和private(受保护的,尽自己可见)两种。

② Linux命令行登录Docker账号

docker login  # 登录docker-hub

③ 修改镜像名称,保持与镜像仓库一致

docker tag joinsunsoft/docker.ui:latest chenjigang/auto-test:v1.1

④ 提交镜像到公共仓库

docker push chenjigang/auto-test:v1.1

⑤ 查看镜像仓库

二、私有化镜像仓库Harbor

1.Harbor简介

Harbor是由VMware公司开源的企业级的Docker Registry管理项目,它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。

作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor 也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。

gitee地址:https://gitee.com/project_harbor/harbor?utm_source=alading&utm_campaign=repo

2.Harbor搭建

安装说明: Harbor的所有服务组件都是在Docker中部署的,所以官方安装使用Docker-compose快速部署,所以需要安装 Docker、Docker-compose。由于Harbor是基于Docker Registry V2版本,所以就要求Docker版本不小于1.10.0, Docker-compose版本不小于1.6.0。

① 下载并解压安装包

在线下载:

wget https://github.com/goharbor/harbor/releases/download/v2.2.2/harbor-online-installer-v2.2.2.tgz
tar -xvf harbor-online-installer-v2.2.2.tgz

② 编辑配置文件

cp harbor.yml.tmpl harbor.yml  # 复制一份harbor.yml文件
vi harbor.yml

按照如下内容编辑:

③ 准备安装环境

./prepare  # 执行prepare脚本

执行完成后,本地会多一个docker-compose.yml文件和common目录

④ 安装harbor

./install.sh  # 安装harbor

安装过程中会自动下载harbor镜像并启动相关容器。

⑤ 访问harbor

安装成功后,即可访问harbor:http://192.168.1.122:8087,其中:ip为本机ip,端口为配置文件harbor.yml中配置的端口。默认账号和密码为:admin Harbor12345

harbor.yml文件中可查看或修改密码

⑥ 安装过程中常见问题及解决

原因:本地已存在redis容器,harbor无法启动redis容器

解决办法:修改harbor目录下docker-compose.yml中的redis容器名称,重新启动

docker-compose up -d

查看harbor各个容器状态:

若本地之前已存在registry容器时,harbor安装过程会报错,解决方案:删除原registry容器,重新执行./install.sh进行安装;若此方式仍报错,则执行docker-compose up -d启动各个服务;

3.推送本地镜像到Harbor

① 创建项目

② Docker登录

由于之前登录过docker-hub,所以再次使用“docker login”命令登录时,默认登录的还是docker-hub的地址。因此,如果想要登录harbor,需要在登录时指定登录地址。

docker login 192.168.1.122:8087

首次登录,根据提示输入harbor用户名及密码即可,与前端登录使用的账号密码一致。

由于我前面登录过一次这个地址,本地会保存认证记录,因此再次登录时无需输入用户名密码即可登录成功。

如遇以下报错:

则要在/etc/docker/daemon.json文件中将本机ip(端口非80时需要带上端口号)加入到insecure-registries列表中,并重载配置。

{
        "registry-mirrors":[
        "http://registry.docker-cn.com",
        "http://docker.mirrors.ustc.edu.cn",
        "http://hub-mirror.c.163.com",
        "http://cr.console.aliyun.com/",
        "https://8wb4g36l.mirror.aliyuncs.com"
],
        "insecure-registries":["192.168.1.122:8087"],
        "graph": "/home/docker_home"
}
systemctl daemon-reload
systectl restart docker

再次登录后登录成功:

③ 本地镜像打tag

镜像名称需要命名为:ip:端口号/项目名称/镜像名:tag名,才能上传到该指定项目下,例如rabbitmq镜像,则名称为:192.168.1.122:8087/harbor/rabbitmq:5.7.33

为了方便测试,我直接复制本地的一个镜像,并重新命名:

docker tag rabbitmq:3.7-management 192.168.1.122:8087/harbor/rabbitmq:3.7-management

④ 推送本地镜像到Harbor

docker push 192.168.1.122:8087/harbor/rabbitmq:3.7-management

查看名为harbor的项目下,存在rabbitmq:3.7-management,测试成功。

⑤ 从Harbor拉取镜像

docker pull 192.168.1.122:8087/library/mysql:5.7.33

从下图可以看出,MySQL镜像已经拉取成功

同时,Harbor管理端也能看到最新的拉取时间:

docker run -it -d -e MYSQL_ROOT_PASSWORD=123456 --name=mysql -p 3307:3306 192.168.1.122:8087/library/mysql:5.7.33

登录MySQL

【docker 可视化管理工具-DockerUI】

一、简介

DockerUI是一款开源的、强大的、轻量级的Docker管理工具。DockerUI覆盖了 docker cli 命令行 95% 以上的命令功能,通过可视化的界面,即使是不熟悉docker命令的用户也可以非常方便的进行Docker和Docker Swarm集群进行管理和维护。

DockerUI后端使用Go语言开发,前台框架使用CubeUI。通过Docker Restful API,经过Go语言编写的Proxy端, 实现和Docker Daemon进行通信,从而实现Docker的管理命令和维护命令。

官网:https ://github.com/gohutool/docker.ui

二、特征

三、安装

1.常规方式安装

1)下载docker.ui源码

git clone https://github.com/gohutool/docker.ui.git

2)安装golang运行环境

① 创建go文件夹

cd /home
mkdir go

② 下载go压缩包并解压缩

https://golang.google.cn/dl/,选择对应系统下载文件

也可以通过wget命令下载:

wget https://golang.google.cn/dl/go1.19.1.linux-amd64.tar.gz
tar -xvf go1.19.1.linux-amd64.tar.gz

③ 添加到环境变量

编辑/etc/profile,添加如下内容:

export GO_HOME=/home/golang/go
export PATH=$PATH:$GO_HOME/bin

④ 重载环境变量

source /etc/profile

⑤ 验证是否安装成功

go --help

出现以下信息表示安装配置成功:

3)项目配置

进入docker.ui项目目录,执行以下命令

export GO111MODULE=on
export GOPROXY="https://goproxy.cn,direct"
go mod tidy
go mod download
go build -o server .  # 执行完成后目录下会多出一个server文件

4)启动服务

./server

2.通过容器安装

1)拉取镜像

docker image pull joinsunsoft/docker.ui

2)创建容器

docker run --restart always --name docker.ui -d -v /home/docker_data/docker.ui/docker.sock:/var/run/docker.sock -p 8999:8999 joinsunsoft/docker.ui

3.浏览器访问

http://192.168.1.122:8999

默认账号密码:ginghan 123456

四、操作快照

镜像列表

搜索/拉取镜像

构建镜像

导入/导出镜像

推送镜像

执行镜像

扫码分享收藏
扫码分享收藏