当前位置: 首页 > news >正文

Docker安装和基本配置

文章目录

  • 简介
      • 镜像和容器
      • 容器和虚拟机
      • 版本介绍
  • 安装流程
      • Windows下的安装
      • Mac下的安装
        • Ubuntu下的安装
      • 备忘记录
  • 部署第一步:容器和镜像
      • Dockerfile
      • 编译和运行
      • 共享镜像
      • 备忘记录
  • 部署第二步:服务和集群
      • docker-compose.yml
      • 运行
      • 验证
      • 重启部署
      • 停止应用和集群
      • 集群效果
      • 备忘记录
  • 部署第三步:可视化
      • 添加节点
  • 附录一:端口占用
  • 附录二:虚拟机相关内容
      • ubuntu检查cpu是否支持虚拟化
        • 安装虚拟机
        • 安装docker-machine
      • docker-machine命令
  • 附录三:Docker的网络类型
  • 附录四:文件配置
  • Docker 安装 Redis
      • 拉取最新镜像
      • 查看本地镜像
      • 运行容器
      • 查看运行
      • 测试
  • Docker 安装 mysql
      • 拉取镜像
      • 查看镜像
      • 启动
      • 容器状态
      • 远程连接

简介

全部操作来自于英文官方文档(两三年前的)。官网地址:https://docs.docker.com/get-started/

docker的优点:
灵活的 Flexible: Even the most complex applications can be containerized.
轻量级 Lightweight: Containers leverage and share the host kernel.
可交互 Interchangeable: You can deploy updates and upgrades on-the-fly.
可移植 Portable: You can build locally, deploy to the cloud, and run anywhere.
可伸缩 Scalable: You can increase and automatically distribute container replicas.
可叠加 Stackable: You can stack services vertically and on-the-fly.

镜像和容器

通过运行镜像image来启动容器。镜像是一个可执行的包,它包含了运行应用程序所需的一切——代码、运行时、库、环境变量和配置文件。
容器是镜像的运行实例,你可以是使用命令docker ps来查看运行情况,就跟在Linux当中一样。
举例来说,就相当于镜像是一个类,容器是镜像的一个实例。

容器和虚拟机

一个容器和主机共享内核,属于轻量级。
相比之下,虚拟机试试建立了一个Guest账户,需要的资源比应用程序所需的多。

版本介绍

Docker两个版本:免费社区版(CE)和收费企业版(EE)。
Docker社区版(CE)有两个更新的渠道,stable和edge:
稳定版stable每季度提供更新
边缘版edge每月提供更新
后续所有的介绍,全部基于社区版。和企业版不同之处见下图:

(img-ubJfKVJ0-1661998976988)(images/screenshot_1661998048891.png)]

安装流程

Docker所有版本的安装步骤可以参看官网,本篇只介绍Docker CE 在Windows10 、 Ubuntu16.04 、 Mac 下的安装。 官网地址:https://docs.docker.com/install/

Windows下的安装

和其他绝大部分软件一样,只需要下载安装包,然后运行完成安装步骤即可。安装包下载地址可以从官网中找到,也可以直接访问https://docs.docker.com/docker-for-windows/install/, 链接中提供的基本的效果。

Mac下的安装

和Windows基本一致,先下载安装包,然后拖拽完成整个步骤。下载地址:https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac
安装完成后,为了加快后续操作加载速度,可以修改下registry mirrors为http://hub-mirror.c.163.com
在这里插入图片描述

Ubuntu下的安装

测试服务器我用了腾讯云的。系统参数如下
在这里插入图片描述

如果电脑已经安装了旧版本的Docker,可以先进行卸载

sudo apt-get remove docker docker-engine docker.io

依次执行以下命令

# 更新apt
sudo apt-get update
# 允许apt访问https
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
# 添加Docker的official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 检查
sudo apt-key fingerprint 0EBFCD88
# 这个是检查的打印结果,不用输入
pub   4096R/0EBFCD88 2017-02-22
      Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-02-22
# 安装stable repository,这个是必须的
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
# 开始安装
sudo apt-get update
sudo apt-get install docker-ce

以上命令安装的是最新版本,如果是生产环境,可能会固定某个版本,通过以下命令查看支持的版本

apt-cache madison docker-ce

有了版本号,就可以安装指定的版本了

$ sudo apt-get install docker-ce=18.03.0~ce-0~ubuntu

安装完成后,查看版本

$ docker --version
Docker version 18.03.0-ce, build 0520e24

详细信息

# 下面两个命令是等价的,用哪个都可以
$ docker version
$ docker info

安装样例(docker镜像,这里先运行就可以,后续章节会有介绍)

$ docker run hello-world

查看已安装样例

$ docker image ls
$ docker container ls --all

备忘记录

# 查看Docker支持的所有命令
docker
docker container --help

# 查看Docker的版本信息和详细信息
docker --version
docker version
docker info

# 运行Docker的镜像
docker run hello-world

# 查看Docker中运行的镜像
docker image ls

# 查看Docker中所有镜像,包括停止的等等
docker container ls
docker container ls --all
docker container ls -aq

部署第一步:容器和镜像

一个项目的部署问题。线上环境安装的JDK版本是1.6,而最新开发完成的项目需要的JDK版本最低是1.8,在1.6的条件下不能正常启动。但是,如果把线上的1.6升级到1.8,旧系统运行又会出现问题。
如果使用了Docker,那么就完全没有这方面的担忧了。Docker是直接运行镜像(image)的,跟服务器的环境无关,需要的运行环境都在镜像当中。如果要自己写个镜像,那么简单说就是需要一个名称是Dockerfile的文件(没有任何后缀,文件名称就是Dockerfile)来定义。
后续的例子都是来自官网,可以去看英文原版:https://docs.docker.com/get-started/part2/#recap-and-cheat-sheet-optional

Dockerfile

这篇主要介绍什么是容器和镜像,涉及到具体语言和业务的,可以暂时不用深究,明白是要干什么的就行。操作环境使用的Ubuntu16.04。
在空白目录下新建名称是Dockerfile的文件

# 目录随意,是空的就行
sudo mkdir /usr/local/test
cd /usr/local/test
sudo vim Dockerfile

文件内容是

# 从远程拉取python需要的运行环境
FROM python:2.7-slim
# 设置工作目录
WORKDIR /app
# 复制当前目录内容到上面设置好的工作目录
ADD . /app
# 安装requirements.txt文件中指定的软件
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 容器端口使用80(不是硬件设备的端口)
EXPOSE 80
# 定义环境变量
ENV NAME World
# 容器启动时运行app.py文件
CMD ["python", "app.py"]

Dockerfile中使用了两个文件,requirements.txt和app.py,在相同目录下新建这两个文件。
requirements.txt的内容

Flask
Redis

app.py的内容

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

以上的含义是完成Flask和Redis的安装,然后打印部分内容,因为Redis没有运行,会打印失败信息。

编译和运行

先确保cd进入了上面文件所在的文件夹,使用下面的命令开始编译,其中friendlyhello是自己定义的名称,最后面有个点(表示当前目录)

sudo docker build -t friendlyhello .

正常情况下,打印的内容为

Sending build context to Docker daemon  4.608kB
Step 1/7 : FROM python:2.7-slim
...(好多内容,忽略不写了)
Step 7/7 : CMD ["python", "app.py"]
 ---> Running in e710f92c9af1
Removing intermediate container e710f92c9af1
 ---> d68b0dcd2d36
Successfully built d68b0dcd2d36
Successfully tagged friendlyhello:latest

上面步骤完成后,就生成镜像了,查看下所有镜像的列表:

$ sudo docker image ls

生成镜像之后自然是运行,执行下面语句:

docker run -p 4000:80 friendlyhello

其中,4000:80的含义是使用计算机真实的4000端口和镜像中的80端口匹配(还记得Dockerfile中定义了一个80吗,不是服务器的,这里可以映射关系),要访问docker中的80端口,只需要访问计算机的4000端口即可。
此时计算机是卡住的状态,要想检查是不是正常,可以使用浏览器查看http://ip地址:4000
自然,我们是不希望窗口一直卡住不能动的(如果要停止, ctrl+c 就行了),能不能后台运行,不影响其他操作呢?只需要加上一个-d,就像其他linux命令一样

docker run -d -p 4000:80 friendlyhello

此时除了用浏览器查看,也可以使用curl命令,就像这样

curl http://localhost:4000

如果运行其实端口被占用,可以参照左侧目录附录一

共享镜像

上面的操作已经可以完成了本地的运行,但是docker还为我们提供了更方便的地方,比如我用mac运行成功了,现在要放到ubuntu服务器上,所有操作都再运行一次是很不方便的,假如我们把运行成功的镜像上传到一个地方,其他计算机要使用的时候,直接拉取这个镜像,岂不是更方便。那么我们就先登录可以放置我们镜像的网站:http://cloud.docker.com
如果没有账号,需要先注册,注册时候验证码会因为网络环境刷新比较吃力,可以换换网络或者找个梯子。我已经注册成功,用户名是fymod。

sudo docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: fymod
Password: 
Login Succeeded

给镜像打个标记username/repository:tag,其中tag是可选的,但是强烈建议加上。

sudo docker tag friendlyhello fymod/get-started:part2

查看下当前运行的镜像是否多出来了fymod/get-started,这个镜像是可以推送到云端的。

sudo docker image ls

把本地镜像推送到云端

$ sudo docker push fymod/get-started:part2

推送完成后,使用注册下来的账号登录https://hub.docker.com/查看,如果有了,其他电脑就可以直接使用。
我们换台只安装了docker的计算机运行下面的命令:

$ sudo docker run -p 4000:80 fymod/get-started:part2

如果本地有这个镜像,就直接使用本地的,如果没有,就从云端拉取,和之前本地运行的命令很相似,只是将之前的friendhello换成了定义的tag。

备忘记录

# 使用Dockerfile建立一个镜像
docker build -t friendlyhello . 
# 前端运行镜像
docker run -p 4000:80 friendlyhello 
# 后台运行镜像
docker run -d -p 4000:80 friendlyhello 
# 列出所有运行中的容器
docker container ls 
# 列出全部容器,即便没有运行
docker container ls -a 
# 停止特定的容器
docker container stop <hash>
# 强制停止指定的容器
docker container kill <hash>
# 移除指定的容器
docker container rm <hash>
# 移除全部容器
docker container rm $(docker container ls -a -q)  
# 查看全部镜像列表
docker image ls -a  
# 移除指定镜像
docker image rm <image id> 
# 移除全部镜像
docker image rm $(docker image ls -a -q)  
# 登录云端
docker login   
# 给要上传云端的镜像打标记
docker tag <image> username/repository:tag 
# 指定标记的镜像上传到云端
docker push username/repository:tag     
# 运行指定标记的镜像
docker run username/repository:tag  

部署第二步:服务和集群

先声明服务和堆栈的概念。上一节介绍了镜像是容器的实例,而服务可以运行很多个容器。比如本篇要讲前一节介绍的demo做成5个容器实例来访问。其实很简单,编写一个yaml格式的文件就行了。本篇对应两篇官方英文网址为:
https://docs.docker.com/get-started/part3/
https://docs.docker.com/get-started/part4/

docker-compose.yml

文件位置没有要求,放到哪里都行。

version: "3"
services:
  web:
    image: fymod/get-started:part2
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:

各个字段含义如下
image:换成自己的镜像
replicas:运行5个容器实例
limits:最大10%的cpu占用和最大50M的RAM占用。
restart_policy:失败之后立即重启
ports:映射外部端口和docker端口
networks:定义了一个默认的网络(支持负载均衡),可查看附录三

运行

sudo docker swarm init
sudo docker stack deploy -c docker-compose.yml getstartedlab

根据docker-compose.yml中的定义,我们的一个服务栈运行5个容器实例,先验证下

sudo docker service ls
sudo docker service ps getstartedlab_web
# 如果想查看系统中全部的容器,可以运行
sudo docker container ls -q

验证

访问http://ip地址,显示的hostname每请求5次一个循环,值就是sudo docker container ls -q当中的数据。

重启部署

如果要把5个实例换成10个,只需要修改docker-compose.yml中的一个数字即可,然后重启。重启的命令和启动的是一模一样,不需要自己先停止再去启动

sudo docker stack deploy -c docker-compose.yml getstartedlab

停止应用和集群

停止应用

$ sudo docker stack rm getstartedlab

停止集群

$ sudo docker swarm leave --force

集群效果

前面已经实现了一台计算机上运行很多容器实例,本部分介绍多台计算机的集群效果。docker集群由管理员和worker组成,本篇使用一台机器作为管理员(就是一直用的这台),另一台(一个安装了docker的新计算机)作为worker。
英文官网上这部分是用的虚拟机,因为我的ubuntu服务器不支持虚拟化,就用了两台物理机。如果要熟悉虚拟机相关注意事项和基本命令,可以先查看左侧附录二。

在一台服务器上执行命令,设置为管理员。

docker swarm init --advertise-addr 10.72.72.98

其中,10.72.72.98是计算机ip地址,替换为自己真实的即可
打印结果如下

Swarm initialized: current node (fszwnygfkgk0tdzlwlc1tuxf3) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-5subd4cg5rjb6hs54b2ctxmihyxgfp32d81suuqqmiks1kawar-44u7f7vlhxydaj8dad35ff4x3 10.72.72.98:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

中间一行命令表示如果要把机器加入到这个集群成为worker,直接把这句复制过去运行。所以在第二台安装了docker的计算机上来直接运行:

docker swarm join --token SWMTKN-1-5subd4cg5rjb6hs54b2ctxmihyxgfp32d81suuqqmiks1kawar-44u7f7vlhxydaj8dad35ff4x3 10.72.72.98:2377

运行完成后可以来查看

sudo docker node ls

命令和之前的也一样:

sudo docker swarm init
sudo docker stack deploy -c docker-compose.yml getstartedlab

查看结果

sudo docker service ls
docker stack ps getstartedlab

访问两台计算机的80端口,看看是不是都有结果,也可以使用curl

curl 管理员计算机ip地址
curl worker计算机ip地址

备忘记录

其他命令可以查看附录二,docker-machine括号里面的都是真机可用的。

# 堆栈和应用列表
docker stack ls    
# 运行指定的组成文件
docker stack deploy -c <composefile> <appname> 
# 列出运行的服务列表
docker service ls  
# 列出与应用程序相关联的任务
docker service ps <service>  
# 检查任务或者容器
docker inspect <task or container>  
# 列出所有容器的id
docker container ls -q   
# 移除应用
docker stack rm <appname>      
# 从管理员移除单一节点
docker swarm leave --force

部署第三步:可视化

回头看下之前的docker-compose.yml,里面只有一个主节点web,用来运行我们demo当中的服务。其实这里面可以添加很多的节点,并非只能添加一个,比如前面例子一直没有实现的redis节点,同时也可以添加docker镜像已经有的可视化节点。这部分英文官方文档地址是:https://docs.docker.com/get-started/part5/

添加节点

修改docker-compose.yml文件,添加两个节点,分别实现可视化和redis管理。

version: "3"
services:
  web:
    image: fymod/get-started:part2
    deploy:
      replicas: 5
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
    ports:
      - "80:80"
    networks:
      - webnet
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
  redis:
    image: redis
    ports:
      - "6379:6379"
    volumes:
      - "/home/docker/data:/data"
    deploy:
      placement:
        constraints: [node.role == manager]
    command: redis-server --appendonly yes
    networks:
      - webnet
networks:
  webnet:

其中,visualizer节点是可视化效果,可以用网页打开查看。redis节点是数据存储用的。因为redis数据最好存储到物理机上,而不是docker中的位置,volumes选项就是将docker中的位置映射到物理机的/home/docker/data目录下。稳妥起见,新建下目录。

sudo mkdir /home/docker/data
sudo mkdir ./data

然后运行

$ sudo docker stack deploy -c docker-compose.yml getstartedlabc

查看

sudo docker service ls

如果redis或者visualizer启动失败,可能是原因是本地没有镜像,也没有成功拉取下来,可以先手动执行下对应的步骤,然后ctrl+c停止

sudo docker run 8080:8080 dockersamples/visualizer:stable
sudo docker run -p 6379:6379 redis

继续运行

$ sudo docker stack deploy -c docker-compose.yml getstartedlabc

网页访问
http://ip地址:8080和http://ip地址查看

附录一:端口占用

比如ssh连接自己断开了,没有使用ctrl+c停止,那么再连接上运行命令的时候,就会提示端口被占用。停止方法:
查看运行的镜像

$ sudo docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
e559c1e88f15        friendlyhello       "python app.py"     36 seconds ago      Up 34 seconds       0.0.0.0:4000->80/tcp   sad_stallman

有了上面的编码,就能直接停止了,序号可以只输入一部分,比如

$ sudo docker container stop e559c

附录二:虚拟机相关内容

ubuntu检查cpu是否支持虚拟化

$ sudo apt-get install cpu-checker
$ kvm-ok

支持的话,打印的是

INFO: /dev/kvm exists
KVM acceleration can be used

不支持的话,打印的是

INFO: Your CPU does not support KVM extensions
INFO: For more detailed results, you should run this as root
HINT:   sudo /usr/sbin/kvm-ok

安装虚拟机

如果支持虚拟化,安装虚拟机

sudo apt-get install libqt5x11extras5 libsdl1.2debian
sudo apt-get install virtualbox

当然也可以自己手动下载下来,然后安装下载下来的文件。下载地址是https://www.virtualbox.org/wiki/Linux_Downloads
安装命令是

$ sudo dpkg -i virtualbox-5.2_5.2.8-121009~Ubuntu~xenial_amd64.deb

安装docker-machine

下面的命令全部复制执行即可

curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

检查用

$ sudo docker-machine version

使用 docker-machine 建立 vms

docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2

查看

docker-machine ls

docker-machine命令

# 在Mac, Win7, Linux下建立虚拟机
docker-machine create --driver virtualbox myvm1 
# Win10下建立虚拟机
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 
# 查下关于节点的基本信息
docker-machine env myvm1     
# 集群下节点列表
docker-machine ssh myvm1 "docker node ls"   
# 节点检查
docker-machine ssh myvm1 "docker node inspect <node ID>"    
# 查看加入使用的token
docker-machine ssh myvm1 "docker swarm join-token -q worker" 
# 打开虚拟机的ssh连接,使用exit命令退出
docker-machine ssh myvm1
# 查看集群下节点列表
docker node ls  
# worker撤离集群
docker-machine ssh myvm2 "docker swarm leave"  
# 彻底关闭集群
docker-machine ssh myvm1 "docker swarm leave -f" 
# 虚拟机列表
docker-machine ls 
# 启动当前没有运行的虚拟机
docker-machine start myvm1     
# 查看虚拟机的环境变量
docker-machine env myvm1      
# mac电脑下连接到虚拟机
eval $(docker-machine env myvm1)  
# windows电脑下连接到虚拟机
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression 
# 编译:管理员服务器才能使用的命令
docker stack deploy -c <file> <app>
# 复制文件到节点主目录(ssh连接到管理员服务器)
docker-machine scp docker-compose.yml myvm1:~ 
# 使用ssh编译应用
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"   
# 断开虚拟机连接
eval $(docker-machine env -u)   
# 停止所有运行的虚拟机
docker-machine stop $(docker-machine ls -q)               
# 删除所有虚拟机和他们的磁盘镜像
docker-machine rm $(docker-machine ls -q)

附录三:Docker的网络类型

Docker安装后,默认会创建下面三种网络类型

docker network ls
NETWORK ID     NAME        DRIVER       SCOPE
9781b1f585ae    bridge       bridge       local
1252da701e55    host        host        local
237ea3d5cfbf    none        null        local

启动 Docker的时候,用 --network 参数,可以指定网络类型

docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest /bin/bash

bridge:桥接网络
默认情况下启动的Docker容器,都是使用 bridge,Docker安装时创建的桥接网络,每次Docker容器重启时,会按照顺序获取对应的IP地址,这个就导致重启下,Docker的IP地址就变了

none:无指定网络
使用 --network=none ,docker 容器就不会分配局域网的IP

host: 主机网络
使用 --network=host,此时,Docker 容器的网络会附属在主机上,两者是互通的。
例如,在容器中运行一个Web服务,监听8080端口,则主机的8080端口就会自动映射到容器中。

创建自定义网络:(设置固定IP)
启动Docker容器的时候,使用默认的网络是不支持指派固定IP的,如下

# 错误命令示例
docker run -itd --net bridge --ip 172.17.0.10 centos:latest /bin/bash
6eb1f228cf308d1c60db30093c126acbfd0cb21d76cb448c678bab0f1a7c0df6
docker: Error response from daemon: User specified IP address is supported on user defined networks only.

步骤1: 创建自定义网络

docker network create --subnet=172.18.0.0/16 mynetwork
➜ ~ docker network ls
NETWORK ID     NAME        DRIVER       SCOPE
9781b1f585ae    bridge       bridge       local
1252da701e55    host        host        local
4f11ae9c85de    mynetwork      bridge       local
237ea3d5cfbf    none        null        local

步骤2: 创建Docker容器

docker run -itd --name networkTest1 --net mynetwork --ip 172.18.0.2 centos:latest /bin/bash

附录四:文件配置

本篇文章来自于https://www.jianshu.com/p/2217cfed29d7

先来看一份 docker-compose.yml 文件,不用管这是干嘛的,只是有个格式方便后文解说:

version: '2'
services:
  web:
    image: dockercloud/hello-world
    ports:
      - 8080
    networks:
      - front-tier
      - back-tier

  redis:
    image: redis
    links:
      - web
    networks:
      - back-tier

  lb:
    image: dockercloud/haproxy
    ports:
      - 80:80
    links:
      - web
    networks:
      - front-tier
      - back-tier
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock 

networks:
  front-tier:
    driver: bridge
  back-tier:
driver: bridge

可以看到一份标准配置文件应该包含 version、services、networks 三大部分,其中最关键的就是 services 和 networks 两个部分,下面先来看 services 的书写规则。

  1. image
services:
  web:
    image: hello-world

在 services 标签下的第二级标签是 web,这个名字是用户自己自定义,它就是服务名称。
image 则是指定服务的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。
例如下面这些格式都是可以的:

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
  1. build
    服务除了可以基于指定的镜像,还可以基于一份 Dockerfile,在使用 up 启动之时执行构建任务,这个构建标签就是 build,它可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用它自动构建这个镜像,然后使用这个镜像启动服务容器。
build: /path/to/build/dir

也可以是相对路径,只要上下文确定就可以读取到 Dockerfile。

build: ./dir

设定上下文根目录,然后以该目录为准指定 Dockerfile。

build:
  context: ../
  dockerfile: path/of/Dockerfile

注意 build 都是一个目录,如果你要指定 Dockerfile 文件需要在 build 标签的子级标签中使用 dockerfile 标签指定,如上面的例子。
如果你同时指定了 image 和 build 两个标签,那么 Compose 会构建镜像并且把镜像命名为 image 后面的那个名字。

build: ./dir
image: webapp:tag

既然可以在 docker-compose.yml 中定义构建任务,那么一定少不了 arg 这个标签,就像 Dockerfile 中的 ARG 指令,它可以在构建过程中指定环境变量,但是在构建成功后取消,在 docker-compose.yml 文件中也支持这样的写法:

build:
  context: .
  args:
    buildno: 1
    password: secret

下面这种写法也是支持的,一般来说下面的写法更适合阅读。

build:
  context: .
  args:
    - buildno=1
    - password=secret

与 ENV 不同的是,ARG 是允许空值的。例如:

args:
  - buildno
  - password

这样构建过程可以向它们赋值。

注意:YAML 的布尔值(true, false, yes, no, on, off)必须要使用引号引起来(单引号、双引号均可),否则会当成字符串解析。

  1. command
    使用 command 可以覆盖容器启动后默认执行的命令。
command: bundle exec thin -p 3000

也可以写成类似 Dockerfile 中的格式:

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

4.container_name
前面说过 Compose 的容器名称格式是:
虽然可以自定义项目名称、服务名称,但是如果你想完全控制容器的命名,可以使用这个标签指定:

container_name: app

这样容器的名字就指定为 app 了。

5.depends_on
在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。
例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。

6.dns
和 --dns 参数一样用途,格式如下:

dns: 8.8.8.8

也可以是一个列表:

dns:
  - 8.8.8.8
  - 9.9.9.9

此外 dns_search 的配置也类似:

dns_search: example.com
dns_search:
  - dc1.example.com
  - dc2.example.com
  1. tmpfs
    挂载临时目录到容器内部,与 run 的参数一样效果:
tmpfs: /run
tmpfs:
  - /run
  - /tmp
  1. entrypoint
    在 Dockerfile 中有一个指令叫做 ENTRYPOINT 指令,用于指定接入点,第四章有对比过与 CMD 的区别。
    在 docker-compose.yml 中可以定义接入点,覆盖 Dockerfile 中的定义:
entrypoint: /code/entrypoint.sh

格式和 Docker 类似,不过还可以写成这样:

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

9.env_file
还记得前面提到的 .env 文件吧,这个文件可以设置 Compose 的变量。而在 docker-compose.yml 中可以定义一个专门存放变量的文件。
如果通过 docker-compose -f FILE 指定了配置文件,则 env_file 中路径会使用配置文件路径。

如果有变量名称与 environment 指令冲突,则以后者为准。格式如下:

env_file: .env

或者根据 docker-compose.yml 设置多个:

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

注意的是这里所说的环境变量是对宿主机的 Compose 而言的,如果在配置文件中有 build 操作,这些变量并不会进入构建过程中,如果要在构建中使用变量还是首选前面刚讲的 arg 标签。

  1. environment
    与上面的 env_file 标签完全不同,反而和 arg 有几分类似,这个标签的作用是设置镜像变量,它可以保存变量到镜像里面,也就是说启动的容器也会包含这些变量设置,这是与 arg 最大的不同。
    一般 arg 标签的变量仅用在构建过程中。而 environment 和 Dockerfile 中的 ENV 指令一样会把变量一直保存在镜像、容器中,类似 docker run -e 的效果。
environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET
  1. expose
    这个标签与Dockerfile中的EXPOSE指令一样,用于指定暴露的端口,但是只是作为一种参考,实际上docker-compose.yml的端口映射还得ports这样的标签。
expose:
 - "3000"
 - "8000"
  1. external_links
    在使用Docker过程中,我们会有许多单独使用docker run启动的容器,为了使Compose能够连接这些不在docker-compose.yml中定义的容器,我们需要一个特殊的标签,就是external_links,它可以让Compose项目里面的容器连接到那些项目配置外部的容器(前提是外部容器中必须至少有一个容器是连接到与项目内的服务的同一个网络里面)。
    格式如下:
external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql
  1. extra_hosts
    添加主机名的标签,就是往/etc/hosts文件中添加一些记录,与Docker client的–add-host类似:
extra_hosts:
 - "somehost:162.242.195.82"
 - "otherhost:50.31.209.229"

启动之后查看容器内部hosts:

162.242.195.82  somehost
50.31.209.229   otherhost
  1. labels
    向容器添加元数据,和Dockerfile的LABEL指令一个意思,格式如下:
labels:
  com.example.description: "Accounting webapp"
  com.example.department: "Finance"
  com.example.label-with-empty-value: ""
labels:
  - "com.example.description=Accounting webapp"
  - "com.example.department=Finance"
  - "com.example.label-with-empty-value"
  1. links
    还记得上面的depends_on吧,那个标签解决的是启动顺序问题,这个标签解决的是容器连接问题,与Docker client的–link一样效果,会连接到其它服务中的容器。
    格式如下:
links:
 - db
 - db:database
 - redis

使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:

172.12.2.186  db
172.12.2.186  database
172.12.2.187  redis

相应的环境变量也将被创建。

  1. logging
    这个标签用于配置日志服务。格式如下:
logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

默认的driver是json-file。只有json-file和journald可以通过docker-compose logs显示日志,其他方式有其他日志查看方式,但目前Compose不支持。对于可选值可以使用options指定。
有关更多这方面的信息可以阅读官方文档:
https://docs.docker.com/engine/admin/logging/overview/

  1. pid
pid: "host"

将PID模式设置为主机PID模式,跟主机系统共享进程命名空间。容器使用这个标签将能够访问和操纵其他容器和宿主机的名称空间。

  1. ports
    映射端口的标签。
    使用HOST:CONTAINER格式或者只是指定容器的端口,宿主机会随机映射端口。
ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"

注意:当使用HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于60你可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。

  1. security_opt
    为每个容器覆盖默认的标签。简单说来就是管理全部服务的标签。比如设置全部服务的user标签值为USER。
security_opt:
  - label:user:USER
  - label:role:ROLE
  1. stop_signal
    设置另一个信号来停止容器。在默认情况下使用的是SIGTERM停止容器。设置另一个信号可以使用stop_signal标签。
stop_signal: SIGUSR1
  1. volumes
    挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER] 这样的格式,或者使用 [HOST:CONTAINER:ro] 这样的格式,后者对于容器来说,数据卷是只读的,这样可以有效保护宿主机的文件系统。
    Compose的数据卷指定路径可以是相对路径,使用 . 或者 … 来指定相对目录。
    数据卷的格式可以是下面多种形式:
volumes:
  // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /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
  1. volumes_from
    从其它容器或者服务挂载数据卷,可选的参数是 :ro或者 :rw,前者表示容器只读,后者表示容器对数据卷是可读可写的。默认情况下是可读可写的。
volumes_from:
  - service_name
  - service_name:ro
  - container:container_name
  - container:container_name:rw
  1. cap_add, cap_drop
    添加或删除容器的内核功能。详细信息在前面容器章节有讲解,此处不再赘述。
cap_add:
  - ALL

cap_drop:
  - NET_ADMIN
  - SYS_ADMIN
  1. cgroup_parent
    指定一个容器的父级cgroup。
cgroup_parent: m-executor-abcd
  1. devices
    设备映射列表。与Docker client的–device参数类似。
devices:
  - "/dev/ttyUSB0:/dev/ttyUSB0"
  1. extends
    这个标签可以扩展另一个服务,扩展内容可以是来自在当前文件,也可以是来自其他文件,相同服务的情况下,后来者会有选择地覆盖原有配置。
extends:
  file: common.yml
  service: webapp

用户可以在任何地方使用这个标签,只要标签内容包含file和service两个值就可以了。file的值可以是相对或者绝对路径,如果不指定file的值,那么Compose会读取当前YML文件的信息。

  1. network_mode
    网络模式,与Docker client的–net参数类似,只是相对多了一个service:[service name] 的格式。
    例如:
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

可以指定使用服务或者容器的网络。

  1. networks
    加入指定网络,格式如下:
services:
  some-service:
    networks:
     - some-network
     - other-network

关于这个标签还有一个特别的子标签aliases,这是一个用来设置服务别名的标签,例如:

services:
  some-service:
    networks:
      some-network:
        aliases:
         - alias1
         - alias3
      other-network:
        aliases:
         - alias2

相同的服务可以在不同的网络有不同的别名。

  1. 其它
    还有这些标签:cpu_shares, cpu_quota, cpuset, domainname, hostname, ipc, mac_address, mem_limit, memswap_limit, privileged, read_only, restart, shm_size, stdin_open, tty, user, working_dir
    上面这些都是一个单值的标签,类似于使用docker run的效果。
cpu_shares: 73
cpu_quota: 50000
cpuset: 0,1

user: postgresql
working_dir: /code

domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43

mem_limit: 1000000000
memswap_limit: 2000000000
privileged: true

restart: always

read_only: true
shm_size: 64M
stdin_open: true
tty: true

Docker 安装 Redis

拉取最新镜像

docker pull redis:latest

查看本地镜像

docker images

运行容器

其中fymod-redis可以任意命名。

docker run -itd --name fymod-redis -p 6379:6379 redis

查看运行

docker ps

测试

先连接上

docker exec -it fymod-redis /bin/bash

使用命令redis-cli测试,添加key如set test 123321

Docker 安装 mysql

拉取镜像

docker pull mysql

查看镜像

docker image ls

启动

docker run --name fymod-mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql

容器状态

docker ps

远程连接

运行docker ps查看到mysql对应的容器id

docker exec -it 容器ID数值 /bin/bash
mysql -uroot -p123456 // 123456是密码
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

相关文章:

  • A40I工控主板(SBC-X40I)LED,铵键测试
  • 中国将从9月起实施严格的新跨境数据传输规则
  • 新唐NUC980使用记录:使用wpa_supplicant访问无线网络
  • 教师教室预约管理系统(SpringBoot,H-UI,Mysql)
  • Centos7五步安装Docker并解决docker官方镜像无法访问问题
  • flink技术总结待续
  • Mac - 安装Nginx
  • SpringBoot事件机制
  • IDEA配置tomcat以及创建项目
  • Node.js | 使用内置模块 event 实现发布订阅模式
  • 七千字详解javaString类
  • 希尔排序算法
  • synchronized同步以及双重检索
  • Codeforce8.29-9.4做题笔记
  • springboot+宴会预定平台 毕业设计-附源码231718
  • [译]CSS 居中(Center)方法大合集
  • 【翻译】babel对TC39装饰器草案的实现
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Elasticsearch 参考指南(升级前重新索引)
  • express如何解决request entity too large问题
  • golang 发送GET和POST示例
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • js
  • mongodb--安装和初步使用教程
  • Node 版本管理
  • React-flux杂记
  • session共享问题解决方案
  • SQLServer之创建显式事务
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 从setTimeout-setInterval看JS线程
  • - 概述 - 《设计模式(极简c++版)》
  • 基于HAProxy的高性能缓存服务器nuster
  • 记一次用 NodeJs 实现模拟登录的思路
  • 深入浅出webpack学习(1)--核心概念
  • 正则表达式
  • 你对linux中grep命令知道多少?
  • FaaS 的简单实践
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​iOS实时查看App运行日志
  • #define、const、typedef的差别
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (九)信息融合方式简介
  • (十三)Flask之特殊装饰器详解
  • .Net core 6.0 升8.0
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .NET建议使用的大小写命名原则
  • .Net中ListT 泛型转成DataTable、DataSet
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • @31省区市高考时间表来了,祝考试成功
  • @JsonFormat与@DateTimeFormat注解的使用