Docker

2023-05-16

概念

Go语言开发,开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

Docker的应用场景

  • Web 应用的自动化打包和发布。
  • 自动化测试和持续集成、发布。
  • 在服务型环境中部署和调整数据库或其他的后台应用。
  • 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。

Docker 的优点

  • 快速,一致地交付您的应用程序
  • 响应式部署和扩展
  • 在同一硬件上运行更多工作负载

Docker 架构

Docker 包括三个基本概念:

  • 镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
  • 容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
容器与镜像的关系类似于面向对象编程中的对象与类。

Docker面向对象
容器对象
镜像

Ubuntu或Debian Docker 安装

使用官方安装脚本自动安装

安装命令如下:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

也可以使用国内 daocloud 一键安装命令:

curl -sSL https://get.daocloud.io/docker | sh

手动安装

卸载旧版本
Docker 的旧版本被称为 docker,docker.io 或 docker-engine 。如果已安装,请卸载它们:

$ sudo apt-get remove docker docker-engine docker.io containerd runc

当前称为 Docker Engine-Community 软件包 docker-ce 。
安装 Docker Engine-Community,以下介绍两种方式。
使用 Docker 仓库进行安装
在新主机上首次安装 Docker Engine-Community 之前,需要设置 Docker 仓库。
设置仓库
更新 apt 包索引。
$ sudo apt-get update
安装 apt 依赖包,用于通过HTTPS来获取仓库:

$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

添加 Docker 的官方 GPG 密钥:

$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 通过搜索指纹的后8个字符,验证您现在是否拥有带有指纹的密钥。

$ sudo apt-key fingerprint 0EBFCD88
    
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

使用以下指令设置稳定版仓库

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

安装 Docker Engine-Community
更新 apt 包索引。
$ sudo apt-get update
安装最新版本的 Docker Engine-Community 和 containerd ,或者转到下一步安装特定版本:

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

要安装特定版本的 Docker Engine-Community,请在仓库中列出可用版本,然后选择一种安装。列出您的仓库中可用的版本:

$ apt-cache madison docker-ce

  docker-ce | 5:18.09.1~3-0~ubuntu-xenial | https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu  xenial/stable amd64 Packages
  docker-ce | 5:18.09.0~3-0~ubuntu-xenial | https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu  xenial/stable amd64 Packages
  docker-ce | 18.06.1~ce~3-0~ubuntu       | https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu  xenial/stable amd64 Packages
  docker-ce | 18.06.0~ce~3-0~ubuntu       | https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu  xenial/stable amd64 Packages
  ...

使用第二列中的版本字符串安装特定版本,例如 5:18.09.13-0ubuntu-xenial。

$ sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

测试 Docker 是否安装成功,输入以下指令,打印出以下信息则安装成功:

$ sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete                                                                                                                                  Digest: sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f
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/

卸载 docker

删除安装包:
sudo apt-get purge docker-ce
删除镜像、容器、配置文件等内容:
sudo rm -rf /var/lib/docker

安装完 docker 后,执行docker相关命令,报错

”Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission denied“
原因:docker进程使用Unix Socket而不是TCP端口。而默认情况下,Unix socket属于root用户,需要root权限才能访问。
解决方法1
使用sudo获取管理员权限,运行docker命令
解决方法2
docker守护进程启动的时候,会默认赋予名字为docker的用户组读写Unix socket的权限,因此只要创建docker用户组,并将当前用户加入到docker用户组中,那么当前用户就有权限访问Unix socket了,进而也就可以执行docker相关命令

sudo groupadd docker     #添加docker用户组
sudo gpasswd -a $USER docker     #将登陆用户加入到docker用户组中
newgrp docker     #更新用户组
docker ps    #测试docker命令是否可以使用sudo正常使用

Docker 镜像加速

国内加速服务器

  • 科大镜像:https://docker.mirrors.ustc.edu.cn/
  • 网易:https://hub-mirror.c.163.com/
  • 阿里云:https://<你的ID>.mirror.aliyuncs.com
  • 七牛云加速器:https://reg-mirror.qiniu.com

Ubuntu14.04、Debian7Wheezy

对于使用 upstart 的系统而言,编辑 /etc/default/docker 文件,在其中的 DOCKER_OPTS 中配置加速器地址:

DOCKER_OPTS="--registry-mirror=https://registry.docker-cn.com"

重新启动服务:
$ sudo service docker restart

Ubuntu16.04+、Debian8+、CentOS7

对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件):

{"registry-mirrors":["https://reg-mirror.qiniu.com/"]}

之后重新启动服务:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

检查加速器是否生效

$ docker info
Registry Mirrors:
    https://reg-mirror.qiniu.com

Docker 容器启动和停止

runoob@runoob:~$ docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world

各个参数解析:

  • docker: Docker 的二进制执行文件。
  • run: 与前面的 docker 组合来运行一个容器。
  • ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
  • /bin/echo ”Hello world“: 在启动的容器里执行的命令

以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo “Hello world”,然后输出结果。

运行交互式的容器

runoob@runoob:~$ docker run -i -t ubuntu:15.10 /bin/bash
root@0123ce188bd8:/#

各个参数解析:

  • -t: 在新容器内指定一个伪终端或终端。
  • -i: 允许你对容器内的标准输入 (STDIN) 进行交互。

注意第二行 root@0123ce188bd8:/#,此时已进入一个 ubuntu15.10 系统的容器
尝试在容器中运行命令 cat /proc/version和ls分别查看当前系统的版本信息和当前目录下的文件列表

root@0123ce188bd8:/#  cat /proc/version
Linux version 4.4.0-151-generic (buildd@lgw01-amd64-043) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) ) #178-Ubuntu SMP Tue Jun 11 08:30:22 UTC 2019
root@0123ce188bd8:/# ls
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@0123ce188bd8:/# 

通过运行 exit 命令或者使用 CTRL+D 来退出容器。

root@0123ce188bd8:/#  exit
exit
root@runoob:~# 

注意第三行中 root@runoob:~# 表明已经退出了当前的容器,返回到当前的主机中。

启动容器(后台模式)

runoob@runoob:~$ docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63

确认容器有在运行,可以通过 docker ps 来查看:

runoob@runoob:~$ docker ps
CONTAINER ID        IMAGE                  COMMAND              ...  
5917eac21c36        ubuntu:15.10           "/bin/sh -c 'while t…"    ...

输出详情介绍:

  • CONTAINER ID: 容器 ID。
  • IMAGE: 使用的镜像。
  • COMMAND: 启动容器时运行的命令。
  • CREATED: 容器的创建时间。
  • STATUS: 容器状态。

状态有7种:

  • created(已创建)
  • restarting(重启中)
  • running 或 Up(运行中)
  • removing(迁移中)
  • paused(暂停)
  • exited(停止)
  • dead(死亡)
  • PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
  • NAMES: 自动分配的容器名称。

在宿主主机内使用 docker logs 命令,查看容器内的标准输出:

runoob@runoob:~$ docker logs 2b1b7a428627


runoob@runoob:~$ docker logs amazing_cori

停止容器

docker stop 2b1b7a428627
也可以用下面的命令来停止:
runoob@runoob:~$ docker stop amazing_cori

Docker 容器使用

Docker 客户端

查看Docker 客户端的所有命令选项
runoob@runoob:~# docker
通过命令 docker command —help 更深入的了解指定的 Docker 命令使用方法
runoob@runoob:~# docker stats --help

容器使用

获取镜像
$ docker pull ubuntu
启动容器
$ docker run -it ubuntu /bin/bash
参数说明:

  • -i: 交互式操作。
  • -t: 终端。
  • ubuntu: ubuntu 镜像。
  • /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。

退出终端
root@ed09e4490c57:/# exit

查询最后一次创建的容器

docker ps -l

启动已停止运行的容器

查看所有的容器命令如下:
$ docker ps -a
启动一个已停止的容器:
$ docker start b750bbbcfd88
后台运行
通过 -d 指定容器的运行模式为后台运行。

$ docker run -itd --name ubuntu-test ubuntu /bin/bash

停止一个容器

停止容器的命令如下:
$ docker stop <容器 ID>

停止的容器可以通过 docker restart 重启:
$ docker restart <容器 ID>

进入容器

进入后台运行的容器

  • docker attach
  • docker exec:推荐使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。

attach 命令
$ docker attach 1e560fca3906
注意: 如果从这个容器退出,会导致容器的停止。
exec 命令
docker exec -it 243c32535da7 /bin/bash

导出和导入容器

导出容器
$ docker export 1e560fca3906 > ubuntu.tar
导入容器快照
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:

$ cat docker/ubuntu.tar | docker import - test/ubuntu:v1

也可以通过指定 URL 或者某个目录来导入,例如:

$ docker import http://example.com/exampleimage.tgz example/imagerepo

删除容器

$ docker rm -f 1e560fca3906

清理掉所有处于终止状态的容器

$ docker container prune

运行一个 web 应用

runoob@runoob:~# docker pull training/webapp  # 载入镜像
runoob@runoob:~# docker run -d -P training/webapp python app.py

参数说明:

  • -d:让容器在后台运行。
  • -P:将容器内部使用的网络端口随机映射到我们使用的主机上。
  • -p 2379:5000 容器内端口5000绑定到主机端口2379

查看网络端口的快捷方式

docker ps

docker port bf08b7f2cd89

查看 WEB 应用程序日志

docker logs -f bf08b7f2cd89
-f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。

查看WEB应用程序容器的进程

docker top wizardly_chandrasekhar

检查 WEB 应用程序

使用 docker inspect 来查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
docker inspect wizardly_chandrasekhar

Docker 镜像使用

列出镜像列表

runoob@runoob:~$ docker images           
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              14.04               90d5884b1ee0        5 days ago          188 MB
php                 5.6                 f40e9e0f10c8        9 days ago          444.8 MB
nginx               latest              6f8d099c3adc        12 days ago         182.7 MB

各个选项说明:

  • REPOSITORY:表示镜像的仓库源
  • TAG:镜像的标签
  • IMAGE ID:镜像ID
  • CREATED:镜像创建时间
  • SIZE:镜像大小

使用 REPOSITORY:TAG 来定义不同的镜像如ubuntu:15.10

查找镜像

比如需要一个 httpd 的镜像来作为我们的 web 服务
docker search httpd

  • NAME: 镜像仓库源的名称
  • DESCRIPTION: 镜像的描述
  • OFFICIAL: 是否 docker 官方发布
  • stars: 类似 Github 里面的 star,表示点赞、喜欢的意思。
  • AUTOMATED: 自动构建。

获取一个新的镜像

预先下载镜像,不写标签获取最新的一个
docker pull ubuntu:13.10

使用镜像

docker run httpd

创建镜像

当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。

  • 1、从已经创建的容器中更新镜像,并且提交这个镜像
  • 2、使用 Dockerfile 指令来创建一个新的镜像

更新镜像

更新镜像之前,我们需要使用镜像来创建一个容器。

runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash
root@e218edb10161:/# 

在运行的容器内使用 apt-get update 命令进行更新。
在完成操作之后,输入 exit 命令来退出这个容器。
此时 ID 为 e218edb10161 的容器,是按需求更改的容器。可以通过命令 docker commit 来提交容器副本。

runoob@runoob:~$ docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
sha256:70bf1840fd7c0d2d8ef0a42a817eb29f854c1af8f7c59fc03ac7bdee9545aff8

各个参数说明:

  • -m: 提交的描述信息
  • -a: 指定镜像作者
  • e218edb10161:容器 ID
  • runoob/ubuntu:v2: 指定要创建的目标镜像名

构建镜像

使用命令 docker build , 从零开始来创建一个新的镜像。为此,需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
例:Dockerfile文件内容

runoob@runoob:~$ cat Dockerfile 
FROM    centos:6.7
MAINTAINER      Fisher "fisher@sudops.com"

RUN     /bin/echo 'root:123456' |chpasswd
RUN     useradd runoob
RUN     /bin/echo 'runoob:123456' |chpasswd
RUN     /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE  22
EXPOSE  80
CMD     /usr/sbin/sshd -D

每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。
通过 docker build 命令来构建一个镜像

runoob@runoob:~$ docker build -t runoob/centos:6.7 .

参数说明:

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

设置镜像标签

docker tag 860c279d2fec runoob/centos:dev
docker tag 镜像ID 用户名/镜像源名:新的标签名

Docker 容器连接

网络端口映射

docker run -d -P training/webapp python app.py
  • -P :是容器内部端口随机映射到主机的端口。
  • -p : 是容器内部端口绑定到指定的主机端口。

指定容器绑定的网络地址

docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py

可以通过访问 127.0.0.1:5001 来访问容器的 5000 端口。

默认都是绑定 tcp 端口,如果要绑定 UDP 端口

unoob@runoob:~$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

Docker 容器互联

容器命名

docker run -d -P --name runoob training/webapp python app.py

查看容器名称

docker ps -l

新建网络

docker network create -d bridge test-net
参数说明:

  • -d:参数指定 Docker 网络类型,有 bridge、overlay。

连接容器

运行一个容器并连接到新建的 test-net 网络:

$ docker run -itd --name test1 --network test-net ubuntu /bin/bash

打开新的终端,再运行一个容器并加入到 test-net 网络:

$ docker run -itd --name test2 --network test-net ubuntu /bin/bash

配置 DNS

全局容器配置

在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:

{
  "dns" : [
    "114.114.114.114",
    "8.8.8.8"
  ]
}

查看容器的 DNS 是否生效

docker run -it --rm  ubuntu  cat etc/resolv.conf

指定容器的配置

$ docker run -it --rm -h host_ubuntu  --dns=114.114.114.114 --dns-search=test.com ubuntu

参数说明:

  • –rm:容器退出时自动清理容器内部的文件系统。
  • -h HOSTNAME 或者 —hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
  • –dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
  • –dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。

如果在容器启动时没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。

Docker 仓库管理

Docker Hub

注册

在 https://hub.docker.com 免费注册一个 Docker 账号。

登录

登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。
$ docker login

退出

退出 docker hub 可以使用以下命令:
$ docker logout

查找官方仓库中的镜像

docker search ubuntu

下载镜像到本地

docker pull ubuntu

推送镜像

用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。
docker push username/ubuntu:18.04

Docker Dockerfile

什么是 Dockerfile?

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

使用 Dockerfile 定制镜像

新建Dockerfile 文件

FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
  • FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
  • RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
    shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的shell 命令。

exec 格式:

RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum -y install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

开始构建镜像

在 Dockerfile 文件的存放目录下,执行构建动作。
以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
注:最后的 . 代表本次执行的上下文路径。
$ docker build -t nginx:v3 .
参数说明:

  • -t :指定要创建的目标镜像名
  • . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
上下文路径

解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。

指令详解

COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
格式:

COPY [--chown=<user>:<group>] <源路径1>...  <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",...  "<目标路径>"]
  • [—chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。
  • <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:
  COPY hom* /mydir/
  COPY hom?.txt /mydir/
  • <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

ADD

ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

  • ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
  • ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:

  • CMD 在docker run 时运行。
  • RUN 是在 docker build。

作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式

CMD <shell 命令> 
CMD ["<可执行文件或命令>","<param1>","<param2>",...] 
CMD ["<param1>","<param2>",...]  # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数

推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。

ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式

ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。
示例
假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参 

1、不传参运行
$ docker run nginx:test
容器内会默认运行以下命令,启动主进程。
nginx -c /etc/nginx/nginx.conf
2、传参运行

$ docker run  nginx:test -c /etc/nginx/new.conf

容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)
nginx -c /etc/nginx/new.conf

ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

以下示例设置 NODE_VERSION = 7.2.0, 在后续的指令中可以通过 $NODE_VERSION 引用

ENV NODE_VERSION 7.2.0

RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
  && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"

ARG

构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 —build-arg <参数名>=<值> 来覆盖
格式
ARG <参数名>[=<默认值>]

VOLUME

定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用
避免重要的数据,因容器重启而丢失,这是非常致命的。
避免容器不断变大。
格式

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。

EXPOSE

仅仅只是声明端口。
作用
帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
格式:
EXPOSE <端口1> [<端口2>...]

WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式
WORKDIR <工作目录路径>

USER

用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式

USER <用户名>[:<用户组>]

HEALTHCHECK

用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:

HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。

ONBUILD

用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式
ONBUILD <其它指令>

LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

比如我们可以添加镜像的作者:

LABEL org.opencontainers.image.authors="runoob"

Docker Compose

Compose 简介

用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

Compose 使用的三个步骤:
  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。
docker-compose.yml配置实例
version: '3'
services:
  web:
    build: .
    ports:
   - "5000:5000"
    volumes:
   - .:/code
    - logvolume01:/var/log
    links:
   - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

Compose 安装

下载

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

将可执行权限应用于二进制文件:

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

创建软链:

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

测试是否安装成功:

$ docker-compose version
cker-compose version 1.24.1, build 4667896b

使用

1、准备

创建一个测试目录:

$ mkdir composetest
$ cd composetest

在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:
composetest/app.py 文件代码

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)


def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)


@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:

flask
redis

2、创建 Dockerfile 文件

内容如下:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]

Dockerfile 内容解释:

  • FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
  • WORKDIR /code: 将工作目录设置为 /code。
  • ENV FLASK_APP app.py
    ENV FLASK_RUN_HOST 0.0.0.0
    设置 flask 命令使用的环境变量。
  • RUN apk add —no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
  • COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    复制 requirements.txt 并安装 Python 依赖项。
  • COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
  • CMD [”flask“, ”run“]: 容器提供默认的执行命令为:flask run。

3、创建 docker-compose.yml

docker-compose.yml 配置文件

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

该 Compose 文件定义了两个服务:web 和 redis。

  • web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
  • redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。

4、使用 Compose 命令构建和运行您的应用

在测试目录中,执行以下命令来启动应用程序:
docker-compose up
如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d

yml 配置指令参考

version
指定本 yml 依从的 compose 哪个版本制定的。
build

version: "3.7"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
      labels:
        - "com.example.description=Accounting webapp"
        - "com.example.department=Finance"
        - "com.example.label-with-empty-value"
      target: prod
  • context:上下文路径。
  • dockerfile:指定构建镜像的 Dockerfile 文件名。
  • args:添加构建参数,这是只能在构建过程中访问的环境变量。
  • labels:设置构建镜像的标签。
  • target:多层构建,可以指定构建哪一层。

cap_add,cap_drop
添加或删除容器拥有的宿主机的内核功能。

cap_add:
  - ALL # 开启全部权限
cap_drop:
  - SYS_PTRACE # 关闭 ptrace权限

cgroup_parent
为容器指定父 cgroup 组,意味着将继承该组的资源限制。
cgroup_parent: m-executor-abcd
command
覆盖容器启动的默认命令。

command: ["bundle", "exec", "thin", "-p", "3000"]

container_name
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
depends_on
设置依赖关系。

  • docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
  • docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。
  • docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
version: "3.7"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

注意:web 服务不会等待 redis db 完全启动 之后才启动。
deploy
指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。

version: "3.7"
services:
  redis:
    image: redis:alpine
    deploy:
      mode:replicated
      replicas: 6
      endpoint_mode: dnsrr
      labels: 
        description: "This redis service label"
      resources:
        limits:
          cpus: '0.50'
          memory: 50M
        reservations:
          cpus: '0.25'
          memory: 20M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s

可选参数:

  • endpoint_mode:访问集群服务的方式。
  • endpoint_mode: vip Docker 集群服务一个对外的虚拟 ip。所有的请求都会通过这个虚拟 ip 到达集群服务内部的机器。
  • endpoint_mode: dnsrr DNS 轮询(DNSRR)。所有的请求会自动轮询获取到集群 ip 列表中的一个 ip 地址。
  • labels:在服务上设置标签。可以用容器上的 labels(跟 deploy 同级的配置) 覆盖 deploy 下的 labels。
  • mode:指定服务提供的模式。
    replicated:复制服务,复制指定服务到集群的机器上。
    global:全局服务,服务将部署至集群的每个节点。
  • replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
  • resources:配置服务器资源使用的限制,例如上例子,配置 redis 集群运行需要的 cpu 的百分比 和 内存的占用。避免占用资源过高出现异常。
  • restart_policy:配置如何在退出容器时重新启动容器。
    condition:可选 none,on-failure 或者 any(默认值:any)。
    delay:设置多久之后重启(默认值:0)。
    max_attempts:尝试重新启动容器的次数,超出次数,则不再尝试(默认值:一直重试)。
    window:设置容器重启超时时间(默认值:0)。
  • rollback_config:配置在更新失败的情况下应如何回滚服务。
    parallelism:一次要回滚的容器数。如果设置为0,则所有容器将同时回滚。
    delay:每个容器组回滚之间等待的时间(默认为0s)。
    failure_action:如果回滚失败,该怎么办。其中一个 continue 或者 pause(默认pause)。
    monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
    max_failure_ratio:在回滚期间可以容忍的故障率(默认为0)。
    order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认 stop-first )。
  • update_config:配置应如何更新服务,对于配置滚动更新很有用。
    parallelism:一次更新的容器数。
    delay:在更新一组容器之间等待的时间。
    failure_action:如果更新失败,该怎么办。其中一个 continue,rollback 或者pause (默认:pause)。
    monitor:每个容器更新后,持续观察是否失败了的时间 (ns|us|ms|s|m|h)(默认为0s)。
    max_failure_ratio:在更新过程中可以容忍的故障率。
    order:回滚期间的操作顺序。其中一个 stop-first(串行回滚),或者 start-first(并行回滚)(默认stop-first)。

devices
指定设备映射列表。

devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"

dns
自定义 DNS 服务器,可以是单个值或列表的多个值。

dns: 8.8.8.8

dns:
  - 8.8.8.8
  - 9.9.9.9

dns_search
自定义 DNS 搜索域。可以是单个值或列表。

dns_search: example.com

dns_search:
  - dc1.example.com
  - dc2.example.com

entrypoint
覆盖容器默认的 entrypoint。
entrypoint: /code/entrypoint.sh
也可以是以下格式:

entrypoint:
    - php
    - -d
    - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
    - -d
    - memory_limit=-1
    - vendor/bin/phpunit

env_file
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
也可以是列表格式:

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

environment
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。

environment:
  RACK_ENV: development
  SHOW: 'true'

expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:

expose:
 - "3000"
 - "8000"

extra_hosts
添加主机名映射。类似 docker client --add-host。

extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:
162.242.195.82 somehost
50.31.209.229 otherhost
healthcheck
用于检测 docker 服务是否健康运行。

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
  interval: 1m30s # 设置检测间隔
  timeout: 10s # 设置检测超时时间
  retries: 3 # 设置重试次数
  start_period: 40s # 启动后,多少秒开始启动检测程序

image
指定容器运行的镜像。以下格式都可以:

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id

logging
服务的日志记录配置。
driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项

driver: "json-file"
driver: "syslog"
driver: "none"

1.仅在 json-file 驱动程序下,可以使用以下参数,限制日志得数量和大小。

logging:
  driver: json-file
  options:
    max-size: "200k" # 单个文件大小为200k
    max-file: "10" # 最多10个文件

当达到文件限制上限,会自动删除旧得文件。

2.syslog 驱动程序下,可以使用 syslog-address 指定日志接收地址。

logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

network_mode
设置网络模式。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks
配置容器连接的网络,引用顶级 networks 下的条目 。

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
      other-network:
        aliases:
         - alias2
networks:
  some-network:
    # Use a custom driver
    driver: custom-driver-1
  other-network:
    # Use a custom driver which takes special options
    driver: custom-driver-2

aliases :同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。
restart

  • no:是默认的重启策略,在任何情况下都不会重启容器。
  • always:容器总是重新启动。
  • on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
  • unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
注:swarm 集群模式,请改用 restart_policy。

secrets
存储敏感数据,例如密码:

version: "3.1"
services:

mysql:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD_FILE: /run/secrets/my_secret
  secrets:
    - my_secret

secrets:
  my_secret:
    file: ./my_secret.txt

security_opt
修改容器默认的 schema 标签。

security-opt:
  - label:user:USER   # 设置容器的用户标签
  - label:role:ROLE   # 设置容器的角色标签
  - label:type:TYPE   # 设置容器的安全策略标签
  - label:level:LEVEL  # 设置容器的安全等级标签

stop_grace_period
指定在容器无法处理 SIGTERM (或者任何 stop_signal 的信号),等待多久后发送 SIGKILL 信号关闭容器。

stop_grace_period: 1s # 等待 1 秒
stop_grace_period: 1m30s # 等待 1 分 30 秒 

默认的等待时间是 10 秒。
stop_signal
设置停止容器的替代信号。默认情况下使用 SIGTERM 。
以下示例,使用 SIGUSR1 替代信号 SIGTERM 来停止容器。
stop_signal: SIGUSR1
sysctls
设置容器中的内核参数,可以使用数组或字典格式。

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0

tmpfs
在容器内安装一个临时文件系统。可以是单个值或列表的多个值。

tmpfs: /run

tmpfs:
  - /run
  - /tmp

ulimits
覆盖容器默认的 ulimit。

ulimits:
  nproc: 65535
  nofile:
    soft: 20000
    hard: 40000

volumes
将主机的数据卷或着文件挂载到容器里。

version: "3.7"
services:
  db:
    image: postgres:latest
    volumes:
      - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
      - "/localhost/data:/var/lib/postgresql/data"

Docker Machine

简介

是一种可以在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机。

安装

安装 Docker Machine 之前你需要先安装 Docker。

Linux 安装命令

$ base=https://github.com/docker/machine/releases/download/v0.16.0 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
  sudo mv /tmp/docker-machine /usr/local/bin/docker-machine &&
  chmod +x /usr/local/bin/docker-machine

Windows 安装命令

如果你是 Windows 平台,可以使用 Git BASH,并输入以下命令:

$ base=https://github.com/docker/machine/releases/download/v0.16.0 &&
  mkdir -p "$HOME/bin" &&
  curl -L $base/docker-machine-Windows-x86_64.exe > "$HOME/bin/docker-machine.exe" &&
  chmod +x "$HOME/bin/docker-machine.exe"

查看是否安装成功:

$ docker-machine version
docker-machine version 0.16.0, build 9371605

使用

1、列出可用的机器

$ docker-machine ls

2、创建机器

创建一台名为 test 的机器。

$ docker-machine create --driver virtualbox test

—driver:指定用来创建机器的驱动类型,这里是 virtualbox。

3、查看机器的 ip

$ docker-machine ip test

4、停止机器

$ docker-machine stop test

5、启动机器

$ docker-machine start test

6、进入机器

$ docker-machine ssh test

docker-machine 命令参数说明

  • $ docker-machine active查看当前激活状态的 Docker 主机。
  • config:查看当前激活状态 Docker 主机的连接信息。
  • create:创建 Docker 主机
  • env:显示连接到某个主机需要的环境变量
  • inspect: 以 json 格式输出指定Docker的详细信息
  • ip: 获取指定 Docker 主机的地址
  • kill: 直接杀死指定的 Docker 主机
  • ls: 列出所有的管理主机
  • provision: 重新配置指定主机
  • regenerate-certs: 为某个主机重新生成 TLS 信息
  • restart: 重启指定的主机
  • rm: 删除某台 Docker 主机,对应的虚拟机也会被删除
  • ssh: 通过 SSH 连接到主机上,执行命令
  • scp: 在 Docker 主机之间以及 Docker 主机和本地主机之间通过 scp 远程复制数据
  • mount: 使用 SSHFS 从计算机装载或卸载目录
  • start: 启动一个指定的 Docker 主机,如果对象是个虚拟机,该虚拟机将被启动
  • status: 获取指定 Docker 主机的状态(包括:Running、Paused、Saved、Stopped、Stopping、Starting、Error)等
  • stop: 停止一个指定的 Docker 主机
  • upgrade: 将一个指定主机的 Docker 版本更新为最新
  • url: 获取指定 Docker 主机的监听 URL
  • version: 显示 Docker Machine 的版本或者主机 Docker 版本
  • help: 显示帮助信息

Swarm 集群管理

简介

Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。 Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。
支持的工具包括但不限于以下各项:

  • Dokku
  • Docker Compose
  • Docker Machine
  • Jenkins

原理

如下图所示,swarm 集群由管理节点(manager)和工作节点(work node)构成。

  • swarm mananger:负责整个集群的管理工作包括集群配置、服务管理等所有跟集群有关的工作。
  • work node:即图中的 available node,主要负责运行相应的服务来执行任务(task)。

在这里插入图片描述

使用

1、创建 swarm 集群管理节点(manager)

创建 docker 机器:

$ docker-machine create -d virtualbox swarm-manager

初始化 swarm 集群

$ docker-machine ssh swarm-manager
$ docker swarm init --advertise-addr 192.168.99.107 #这里的 IP 为创建机器时分配的 ip。

2、创建 swarm 集群的两个工作节点(worker)

$ docker-machine create -d virtualbox swarm-worker1 
$ docker-machine create -d virtualbox swarm-worker1 

3、添加工作节点到管理节点

分别进入工作节点运行在管理节点初始化时复制的命令

docker@swarm-worker1:~$ docker swarm join --token SWMTKN-1-4oogo9qziq768dma0uh3j0z0m5twlm10iynvz7ixza96k6jh9p-ajkb6w7qd06y1e33yrgko64sk 192.168.99.107:2377

4、查看集群信息

管理节点内
docker info

5、部署服务到集群中

注意:跟集群管理有关的任何操作,都是在管理节点上操作的。
以下例子,在一个工作节点上创建一个名为 helloworld 的服务,这里是随机指派给一个工作节点:

docker@swarm-manager:~$ docker service create --replicas 1 --name helloworld alpine ping docker.com

6、查看服务部署情况

查看 helloworld 服务运行在哪个节点上

docker@swarm-manager:~$ docker service ps helloworld

查看 helloworld 部署的具体信息:

docker@swarm-manager:~$ docker service inspect --pretty helloworld

7、扩展集群服务

我们将上述的 helloworld 服务扩展到俩个节点。

docker@swarm-manager:~$ docker service scale helloworld=2

8、删除服务

docker@swarm-manager:~$ docker service rm helloworld

9、滚动升级服务

创建一个 3.0.6 版本的 redis。

docker@swarm-manager:~$ docker service create --replicas 1 --name redis --update-delay 10s redis:3.0.6

滚动升级 redis 。

docker@swarm-manager:~$ docker service update --image redis:3.0.7 redis

10、停止某个节点接收新的任务

查看所有的节点:
docker@swarm-manager:~$ docker node ls

停止节点 swarm-worker1:
docker@swarm-manager:~$ docker node update --availability drainls swarm-worker1
注意:swarm-worker1 状态变为 Drain。不会影响到集群的服务,只是 swarm-worker1 节点不再接收新的任务,集群的负载能力有所下降。
重新激活节点:

docker@swarm-manager:~$  docker node update --availability active swarm-worker1

Docker 安装 Ubuntu

拉取最新版的 Ubuntu 镜像

$ docker pull ubuntu

查看本地镜像

$ docker images

运行容器,并且可以通过 exec 命令进入 ubuntu 容器

$ docker run -itd --name ubuntu-test ubuntu

查看容器的运行信息

docker ps

Docker 安装 CentOS

拉取指定版本的 CentOS 镜像

$ docker pull centos:centos7

查看本地镜像

$ docker images

运行容器,并且可以通过 exec 命令进入 CentOS 容器。

$ docker run -itd --name centos-test centos:centos7

查看容器的运行信息

docker ps

Docker 安装 Nginx

查看可用版本

docker search nginx

取最新版的 Nginx 镜像

$ docker pull nginx

查看本地镜像

$ docker images

运行容器

$ docker run --name nginx-test -p 8080:80 -d nginx

参数说明:

  • —name nginx-test:容器名称。
  • -p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
  • -d nginx: 设置容器在在后台一直运行。

安装成功

最后我们可以通过浏览器可以直接访问 8080 端口的 nginx 服务

Docker 安装 Node.js

查看可用版本

docker search node

取最新版的 node 镜像

$ docker pull node:latest

查看本地镜像

$ docker images

运行容器

$ docker run -itd --name node-test node
参数说明:

  • –name node-test:容器名称。

安装成功

$ docker exec -it node-test /bin/bash
root@6c5d265c68a6:/# node -v

Docker 安装 MySQL

查看可用版本:

$ docker search mysql

拉取 MySQL 镜像

$ docker pull mysql:latest

查看本地镜像

$ docker images

运行容器

$ docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

参数说明:

  • -p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 MySQL 的服务。
  • MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 root 用户的密码。

安装成功

docker ps

进入容器

docker exec -it mysql bash

登录mysql

mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Lzslov123!';

添加远程登录用户

CREATE USER 'liaozesong'@'%' IDENTIFIED WITH mysql_native_password BY 'Lzslov123!';
GRANT ALL PRIVILEGES ON *.* TO 'liaozesong'@'%';

Docker 安装 Tomcat

查看可用版本:

docker search tomcat

取官方的镜像:

runoob@runoob:~/tomcat$ docker pull tomcat

在本地镜像列表里查看REPOSITORY 为 tomcat 的镜像

runoob@runoob:~/tomcat$ docker images|grep tomcat

Docker 安装 Redis

查看可用版本:

docker search redis

取最新版的 Redis 镜像

$ docker pull redis:latest

查看本地镜像

$ docker images

运行容器

$ docker run -itd --name redis-test -p 6379:6379 redis

参数说明:

  • -p 6379:6379:映射容器服务的 6379 端口到宿主机的 6379 端口。外部可以直接通过宿主机ip:6379 访问到 Redis 的服务。

安装成功

docker ps

通过 redis-cli 连接测试使用 redis 服务

$ docker exec -it redis-test /bin/bash

Docker 安装 MongoDB

查看可用的 MongoDB 版本

docker search mongo

取最新版的 MongoDB 镜像

$ docker pull mongo:latest

查看本地镜像

$ docker images

运行容器

$ docker run -itd --name mongo -p 27017:27017 mongo --auth

参数说明:

  • -p 27017:27017 :映射容器服务的 27017 端口到宿主机的 27017 端口。外部可以直接通过 宿主机 ip:27017 访问到 mongo 的服务。
  • —auth:需要密码才能访问容器服务。

安装成功

docker ps

接着使用以下命令添加用户和设置密码,并且尝试连接。

$ docker exec -it mongo mongo admin
#创建一个名为 admin,密码为 123456 的用户。
>  db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
# 尝试使用上面创建的用户信息进行连接。
> db.auth('admin', '123456')

Docker 安装 Apache

拉取官方的镜像

runoob@runoob:~/apache$ docker pull httpd

运行容器

docker run -p 80:80 -v $PWD/www/:/usr/local/apache2/htdocs/ -v $PWD/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf -v $PWD/logs/:/usr/local/apache2/logs/ -d httpd

命令说明:

  • -p 80:80:第一个 80 端口为主机端口,后面一个是容器端口,效果为将容器的 80 端口映射到主机的 80 端口。
  • -v $PWD/www/:/usr/local/apache2/htdocs/: 将主机中当前目录下的 www 目录挂载到容器的 /usr/local/apache2/htdocs/。
  • -v $PWD/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf: 将主机中当前目录下的 conf/httpd.conf 文件挂载到容器的 /usr/local/apache2/conf/httpd.conf。
  • -v $PWD/logs/:/usr/local/apache2/logs/: 将主机中当前目录下的 logs 目录挂载到容器的 /usr/local/apache2/logs/。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker 的相关文章

随机推荐

  • 2022年嵌入式开发就业前景怎么样?

    时间 xff1a 2022年5月26号 xff01 这几年嵌入式开发的发展前景可以说是非常的香 xff01 从工资和找工作的难易程度上说都是 xff01 按老师傅的说法就是 xff1a 加班不严重 xff0c 注重积累 xff0c 越往底层
  • ARM结构体系3:ARM指令的寻址和异常中断处理

    目录 ARM处理器的八种寻址方式 1 立即数寻址 2 寄存器寻址 3 寄存器间接寻址 4 寄存器移位寻址 5 基址变址寻址 6 多寄存器寻址 7 相对寻址 8 堆栈寻址 9 GNU汇编伪指令 异常中断处理 1 7种异常源 2 异常向量表 A
  • 51单片机(ESP8266模块)

    前言 xff1a 蓝牙 xff0c ESP 01s xff0c Zigbee NB Iot等通信模块都是基于AT指令的设计 一 AT指令 AT指令集是从终端设备 xff08 Terminal Equipment xff0c TE 或数据终端
  • 嵌入式工作机会会越来越少吗

    我认为嵌入式工作会越来越多 在当前产业结构升级的大背景下 xff0c 物联网会与诸多的行业领域产生更加紧密的联系 xff0c 而这个过程必然离不开嵌入式开发的参与 应用场景对于嵌入式开发领域的发展有非常直接的影响 xff0c 嵌入式开发要想
  • 大学生为何很想往嵌入式方向发展?

    这几年嵌入式工资一直在再涨 xff0c 挺好的 xff01 可以选择的公司也比较多 xff0c 起薪差不读在10k 13k的样子 招聘公司统计的数据是19K 优点1 xff1a 应届生嵌入式行业的薪资在毕业生眼里看来真的是很香 xff0c
  • 涨姿势 | 一文说透电机控制器硬件在环测试(MCU HIL)

    软件质量是嵌入式产品开发中最关注的问题之一 随着产品迭代 xff0c 软件复杂程度越来越高 xff0c 为保证软件质量 xff0c 需要对软件进行大量的测试 xff0c 这会在整个产品周期中消耗大量时间及资源 另一方面 xff0c 市场竞争
  • VMware Workstation创建Windows 11(21H2)虚拟机

    2021年6月24日 xff0c 微软发布了Windows 11 xff0c 很多人都想 尝尝鲜 可以为较高的电脑配置 xff0c 使得很多老电脑 望而却步 xff0c 或者有人想换可又嫌麻烦或不舍得 所以今天我来带大家创建Windows
  • 计算机知识——常见的存储类型

    一 常见存储器类型 xff1a 1 易失 非易失性存储器 xff1a 是指存储器断电后 xff0c 它存储的数据内容是否会丢失的特性 由于一般易失性存储器存取速度快 xff0c 而非易失性存储器可长期保存数据 易失性存储器最典型的代表是内存
  • 使用select函数实现TCP并发服务器

    首先介绍一下select 函数的功能 参数 返回值 int select int nfds fd set readfds fd set writefds fd set exceptfds struct timeval timeout voi
  • ROS下gazebo打不开,最新最全的可行方法

    问题具体描述 xff1a 在打开roscore的情况下 执行命令行 xff1a rosrun gazebo ros gazebo 或者命令行 xff1a roslaunch gazebo ros empty world launch 但是只
  • 西门子S7-200SMART模拟量输入、输出模块接线

    西门子S7 200SMART模拟量输入 输出模块接线 https www bilibili com video BV1J3411R7nu spm id from 61 333 337 search card all click 西门子S7
  • SyntaxError: Non-ASCII character ‘\xe9‘报错

    本人在用vscode写python代码时 xff0c 第一次运行就遇到了这种情况 解决方法 xff1a 在python文件开头加上以下一行 xff1a coding utf 8 如下图所示 xff1a 即可解决报错问题 xff08 注意 x
  • 最新:ubuntu18.04下,vscode报错:No such file or directory

    我遇到的问题是 xff1a 在vscode编译下是没有报错的 xff0c 但是运行文件时 xff0c 还是报错了 如下图所示 xff1a 实际上 xff0c vscode会经常遇到这种类似的问题 xff0c 建议可以使用ubuntu的终端运
  • 打开了ros中的rviz,显示不了机器人模型

    问题 xff1a 可以打开gazebo xff0c 但是打开rviz后 xff0c 显示不了机器人模型 报错情况如下图所示 xff1a 解决 xff1a 看看自己的launch文件是否加了以下的节点 xff1a lt node pkg 61
  • 在vscode的界面的竖线光标变成灰色方块,怎么解决?(最全方法集合)

    具体情况如下图所示 xff1a 原因 xff1a 是vscode安装了vim xff0c 所以会出现这种情况 解决方法 xff1a 1 点一下insert键 xff0c 可以单次取消灰色方块的出现 xff0c 但是不能根除灰色方块 2 卸载
  • 给keil5加芯片包(PACK)

    按照这个链接来安装即可 xff0c 非常的详细和简单 https blog csdn net qq 45931949 article details 125219598
  • Invoking “make -j1“ failed

    Invoking 34 make j1 34 failed 在进行catkin make j1 的单线程编译时 xff0c 出现了很玄学的问题 xff0c 就是一会编译成功 xff0c 之后重新编译又报这个错误 xff0c 终端报错的是这个
  • find a package configuration file provided by “GeographicLib“, but CMake did not find one.

    在编译kitty数据集时 xff0c 编译不通过 xff0c 发现是安装的系统没有安装GeographicLib库 xff0c 所以报错了 xff0c 解决方法就是自己安装就可以了 xff0c 命令行如下 xff1a git clone h
  • fatal error: glog/logging.h: 没有那个文件或目录

    compilation terminated lidar localization CMakeFiles hello kitti node dir build make 206 recipe for target 39 lidar loca
  • Docker

    概念 Go语言开发 xff0c 开发者打包他们的应用以及依赖包到一个轻量级 可移植的容器中 xff0c 然后发布到任何流行的 Linux 机器上 xff0c 也可以实现虚拟化 容器是完全使用沙箱机制 xff0c 相互之间不会有任何接口 xf