代码编织梦想

文章目录

1. Docker学习笔记

1.1. Docker简介

  • Docker是目前最火的开源项目之一
  • 由Docker公司开发
  • 托管于github docker地址
  • go语言编写
  • 提供了打包,传输,运行任意应用的容器解决方案
  • 适用于Linux,Windows,Mac平台
  • 简单易用

1.2. Ubuntu安装Docker CE(社区版)

Ubuntu系统上安装Docker

1.2.1. 卸载旧版本

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

1.2.2. 使用存储库安装

安装步骤:

1.2.2.1. 设置存储库

  1. 更新软件包索引

    sudo apt-get update
    
  2. 安装包以允许apt通过HTTPS使用存储库:

    sudo apt-get install \
    apt-transport-https \
    curl \
    gnupg-agent \
    software-properties-common
    
  3. 添加Docker官方GPG密匙

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    

    通过搜索指纹的最后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]
    
  4. 使用以下命令设置稳定存储库。要添加nightlytest存储库,请在下面的命令中的单词后添加单词nightlytest(或两者)stable。了解夜间和测试频道.
    x86_64/arm64处理器使用一下命令

    sudo add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"
    

1.2.2.2. 安装Docker CE

  1. 更新apt包索引

    sudo apt-get update
    
  2. 安装最新的docker CE 和 containerd

    sudo apt-get install docker-ce docker-ce-cli containerd.io
    
  3. 安装特定版本的Docker CE
    列出可用版本

    apt-cache madison docker-ce
    

    例如,使用版本5:18.09.1-3-0-ubuntu-xenial

    sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io
    
  4. 运行hello-word验证是否正确安装了Docker CE

    sudo docker run hello-word
    

此时Docker CE 已经正确安装. docker组已经创建,但是尚未向其添加任何用户.

1.2.2.3. 升级 Docker CE

先运行sudo apt-get update, 然后按要求选择版本

1.2.3. 卸载 Docker CE

  1. 卸载Docker CE软件包

    sudo apt-get purge docker-ce
    
  2. 主机上的图像,容器,卷或自定义配置文件不会自动删除。要删除所有图像,容器和卷:

    sudo rm -rf /var/lib/docker
    

1.3. Docker 可选设置

1.3.1. 创建Docker组,并添加用户

Docker守护程序绑定到Unix套接字而不是TCP端口。默认情况下,Unix套接字由用户拥有root,其他用户只能使用它sudo。Docker守护程序始终以root用户身份运行。

如果您不想在docker命令前加上sudo,请创建一个名为的Unix组docker并向其添加用户。当Docker守护程序启动时,它会创建一个可由该docker组成员访问的Unix套接字。

  1. 创建Docker组

    sudo groupadd docker
    
  2. 将我的用户添加到Docker组

    sudo usermod -aG docker $USER
    
  3. 注销账户重新登录

1.3.2. 配置Docker以在启动计算机时启动

大多数的Linux发行版使用systemd命令,Ubuntu 14.10及以下使用upstart。

sudo systemctl enable docker

如果要禁止自启动

sudo systemctl disable docker

1.4. CentOS安装Docker CE(社区版)

1.4.1. 卸载旧版本

使用一下命令卸载


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

docker images,containers,volumes,networks 保存在/var/lib/docker/目录中.

1.4.2. 安装Docker CE 存储库

第一次安装之前,你需要设置Docker存储库. 之后,你可以在存储库中安装和升级.

  1. 安装需要的包. yum-utils 提供yum-config-manager功能, 并且存储驱动程序需要device-mapper-persistent-data
    devicemapper

    sudo yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2
    
  2. 使用以下命令设置稳定版存储库

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

1.4.3. 可选项

Docker CE 有三个版本:

  • Stable : 稳定版
  • Test : 测试版
  • Nightly : 开发版
  1. 可以设置开发版版本库

    sudo yum-config-manager --enable docker-ce-nightly
    
  2. 设置测试版存储库

    sudo yum-config-manager --enable docker-ce-test
    
  3. 可以关闭开发版或者测试版 存储库, 使用命令: yum-config-manager --disable .

    sudo yum-config-manager --disable docker-ce-nightly
    

1.4.4. 安装Docker CE

  1. 安装最新版的Docker CEcontainerd .

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

    如果安装了多个存储库

    如果有多个Docker版本存储库可以使用,那么使用yum > install 或者 yum update 安装时, 系统会自动选> 择最新的版本安装. 如果要安装特定的版本, 请看步骤2.

  2. 安装特定版本的Docker

    a. 列出Docker CE 的版本

    yum list docker-ce --showduplicates | sort -r
    
    

    b. 根据版本的包名称,安装特定版本.

     sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
    
  3. 启动Docker

    sudo systemctl start docker
    
  4. 验证是否安装成功. 运行测试映像, hello-world

    sudo docker run hello-world
    

    此命令会下载一个测试映像.

现在Docker 已经安装完成, Docker 需要管理员权限才能运行. 如果你是非管理员用户,且不想用sudo命令, 可以设置(Linux postinstall)[https://docs.docker.com/install/linux/linux-postinstall/]

1.5. 入门

1.5.1. 第1部分:方向和设置

1.5.1.1. Docker的概念

Docker是开发人员和系统管理人员使用容器开发,部署,运行应用程序的平台. 使用Linux容器部署应用程序称为容器化.

Docker的优点:

  • 灵活: 即使是最复杂的应用也可以集成装箱化
  • 轻量级: 各个容器共享主机内核
  • 可互换: 可以及时部署和更新
  • 便携性: 可以本地构建,部署到云,并在任何地方运行它
  • 可扩展: 可以增加并自动分发容器的副本
  • 可堆叠: 可以垂直和即时堆叠服务

1.5.1.2. Images and containers(映像和容器)

容器是通过运行一个映像来启动.映像是一个可执行的包,它包含了所有运行一个目标程序所需要的: 代码,运行环境, 函数库, 环境变量, 配置文件.

容器是映像的一个运行实例.可以使用命令docker ps 来列出当前在运行的容器

1.5.1.3. Containers and virtual machines(容器和虚拟机)

一个容器运行在原生的Linux上并且和其他容器共享主机内核. 它运行在一个独立的进程中,并不比其他可自行程序占用更多的内存,使得容器是轻量级的.

相比之下,虚拟机通过管理程序使用虚拟通道在主机上运行一个成熟的系统. 总之,虚拟机提供了一个远超过目标程序所需要的环境资源.

1.5.1.4. 安装Docker

见开头

1.5.1.5. Test Docker version

  1. 参看版本信息

    docker --version
    
  2. 查看更多详细信息

    docker info
    

    docker version
    

1.5.1.6. Test Docker installation

  1. 运行hello-word测试

    docker run hello-word
    
  2. 列出已经下载到本地的映像

    docker image ls
    
  3. 列出所有的容器, --all 表示包括没有运行的

    docker container ls --all
    

1.5.1.7. Recap and cheat sheet(回顾和备忘单)

## List Docker CLI commands
docker
docker container --help

## 列出Docker版本和信息
docker --version
docker version
docker info

## 执行docker映像
docker run hello-world

## 列出docker镜像
docker image ls

## 列出Docker容器(running,all,all in quiet mode)
docker container ls
docker conainer ls --all
docker conainer ls -aq

1.5.2. 第2部分: 容器

1.5.2.1. Introduction

现在可以使用docker创建app.

  • Stack(栈)
  • Server(服务)
  • Container(容器)

1.5.2.2. Your new development environment

在过去, 如果你要写一个Python程序, 你的第一个任务是安装一个Python运行环境在你的机器上. 但是, 这会使你的计算机的运行环境既要运行你的app,又要匹配你的生产环境.

使用Docker, 你可以抓取一个便携的Python运行环境作为一个映像,没有必要安装. 然后, 你的构建可以包含基础的Python运行环境作为一个映像,确保你的app的依赖,运行环境等一起工作.

1.5.2.3. Define a container with Dockerfile (使用Dockerfile文件定义容器)

Dockerfile 定义那些程序运行在你的容器内的环境上. 有权使用的资源,例如:网络接口和磁盘在环境上是虚拟化的, 它是和电脑的其他部分相隔离的, 所以需要向外界露出接口, 确定什么文件需要复制到容器环境中. 做好这些之后,你可以期待定义在Dockerfile 中的你的app的构建无论在哪里都可以有相同的运行表现.

Dockerfile

在本机计算机上创建一个空文件夹. 在该文件夹中创建一个名为Dockerfile的文件, 将以下信息复制粘贴到改文件中.

# Use an official Python runtime as a parent image
# 使用官方的Python运行环境作为一个母映像
FROM python:2.7-slim

# Set the working directory to /app
# 设置工作目录为 /app
WORKDIR /app

# Copy the current directory contents into the container at /app
# 复制当前目录的内容到容器中的 /app
COPY . /app

# Install any needed packages specified in requirements.txt
# 安装任何在requirements.txt中指定的包
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
# 该容器向外界开发80端口
EXPOSE 80

# Define environment variable
# 定义环境变量
ENV NAME World

# Run app.py when the container launches
# 当容器启动时,运行app.py
CMD ["python", "app.py"]

Dockerfile引用的文件 app.py , requirements.txt . 接下来创建他们.

1.5.2.4. The app itself

创建至少两个文件requirements.txt , app.py ,将它们和Dockerfiler 放入同一文件夹. 这便完成了我们的程序. 当上述的Dockerfile 被构建到一个映像中, app.pyrequirements.txt被表达, 因为DockerfileCOPY命令. 并且输出文件app.py 可以通过HTTP获得,是由于 EXPOSE 命令.

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)

现在可以发现pip install -r requirements.txt 安装FlaskRedisPython库, 并且app输出环境变量NAME, 同时调用输出socket.gethostname(). 最后Redis没有运行(因为我们只安装了Python库,并不是Redis本身),我们期望尝试使用它出错并且输出错误信息.

注意: 在容器内部访问容器ID时,访问主机名称, 如同进程ID一样.

你不需要Python或者其他在requirements.txt文件中的东西在你的系统中, 也不需要构建或者运行映像安装到你的系统中. 似乎也没有真正设置Python环境.

1.5.2.5. Build the app

现在开始构建应用程序,打开上述建立的根目录.目录中的文件包括:

$ ls
Dockerfile		app.py			requirements.txt

运行build命令, 它将创建一个Docker映像, --tag= 将设置映像的名称.-t是缩写.

docker build --tag=friendlyhello .
# 注意最后的一个`.`,表示当前文件夹中的所有文件

创建的镜像将会在本地计算机的Docker映像仓库.

docker image ls
REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

注意 标签项是lstest, 如果要加入版本号, 完整的tag设置, --tag=friendlyhello:v0.0.1

linux用户故障排除

代理服务器设置

代理服务器可能在启动时阻塞你的web应用的连接. 如果你在代理服务器的后面, 加入一下内容在你的Dockerfile文件中, 使用ENV命令
来指定你的代理服务器的host和port.

# Set proxy server, replace host:port with values for your servers
ENV http_proxy host:port
ENV https_proxy host:port

DNS setting

DNS 的错误设置可能会产和pip 产生错误. 你需要设置自己的DNS server地址来使pip正常工作. 你可以更改Docker进程守护的DNS,编辑在/etc/docker/daemon.json中的配置文件.如下:

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

上述设置中,第一是你自己的DNS server , 第二个是备用的Google DNS(在中国可以正常使用?)

保存daemon.json 并且重启docker服务.

sudo server docker restart

修复完成后尝试重置运行build命令

1.5.2.6. Run the app

运行应用, 使用-p命令匹配计算机的4000端口到容器的端口80.

docker run -p 4000:80 friendlyhello

现在可以在看见Python在http://0.0.0.0:80为你的应用提供消息. 但是该消息来着容器内部, 我们已经将容器的80端口映射到主机的4000端口, 所以在浏览器中访问http://localhost:4000

4000:80端口的重映射说明了Dockerfile 中的EXPOSEpublish值在启动docker run -p 时的不同.

使用ctrl + c来退出容器.

现在让我们在后台以分离模式运行应用程序:

docker run -d -p 4000:80 friendlyhello

此时获得容器的长ID,并且容器在后台运行. 可以使用docker container ls命令查看 容器ID.

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

使用docker container stop progressID来停止进程.

docker container stop 1fa4ab2cf395

1.5.2.7. Share your image

为了证明我们创建的容器的可移植性,上传我们构建的image并且在其他地方运行它.

注册表是仓库的集合, 仓库是映像的集合. 许多代码仓库,例如Github, 会排除已经构建的代码. 注册表上的一个账号可以创建许多仓库. docker命令行默认使用Docker的公共注册表.

也可以选择其他的注册表,Docker Trusted Registry

1.5.2.8. Log in with your Docker ID

注册一个Docker账号 hub.docker.com.在本地登录使用:

docker login

1.5.2.9. Tag the image

结合本地映像和注册表上的仓库的标记是username/repository:tag . 这个标记是可选的, 但是推荐选择. 它的作用是给image一个版本号. 给仓库和版本号一个有意义的名字,例如get-started:part2,它将会把映像放在get-started仓库中并且标记它为part2 .

保存映像:

docker tag image username/repository:tag

例如:

docker tag friendlyhello gordon/get-started:part2

查看映像:

docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
gordon/get-started         part2               d9e555c53008        3 minutes ago       195MB
python                   2.7-slim            1c7128a655f6        5 days ago          183MB

1.5.2.10. Publish the image

上传你标记的映像到仓库:

docker push username/repository:tag

完成之后登录Docker Hub.

1.5.2.11. Pull and run the image from the remote repository

使用docker run命令在其他机器上运行.

docker run -p 4000:80 username/repository:tag

如果本地没有该映像, Docker将会从仓库中拉去下来.

 docker run -p 4000:80 gordon/get-started:part2
Unable to find image 'gordon/get-started:part2' locally
part2: Pulling from gordon/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for gordon/get-started:part2
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

无论在哪运行docker run 命令, 它都会拉去你的映像,并且会拉去所有在requirements.txt中的依赖文件, 并且运行你的代码. 它们将会在一个小而紧凑的包里运行, 不需要再安装额外的软件.

1.5.2.12. Recap and cheat sheet(回顾和备忘单)


docker build -t friendlyhello .  # 使用Dockerfile创建映像
docker run -p 4000:80 friendlyhello  # Run "friendlyhello" mapping port 4000 to 80
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)         # Remove all containers
docker image ls -a                             # List all images on this machine
docker image rm <image id>            # Remove specified image from this machine
docker image rm $(docker image ls -a -q)   # Remove all images from this machine
docker login             # Log in this CLI session using your Docker credentials
docker tag <image> username/repository:tag  # Tag <image> for upload to registry
docker push username/repository:tag            # Upload tagged image to registry
docker run username/repository:tag                   # Run image from a registry

1.5.3. 第3部分: services

在第三部分, 规划我们的应用程序并且使其加载均衡. 为了实现它,我们要在分布式应用程序的上一层:server层.

  • Stack
  • Services
  • Container

1.5.3.1. About services

在一个分布式的应用中, app的不同部分被称为services. 例如, 如果你想建立一个视频分享网站, 当用户上传了一个视频之后一个转码的服务将在后台运行, 并且前端服务等程序在运行.

servives 仅仅是 containers in production . 服务仅仅运行在一个image 上, 但是它编码了映像运行的方式:它应该运行在那些端口,应该运行多少的副本,等等. 扩展服务会增加运行程序的容器实例的数量, 会分配更多的计算机资源给服务进程.

在Docker中,定义,运行,和规划服务将会非常容易. --仅仅写一个docker-compose.yml文件即可.

1.5.3.2. Your first docker-compose.yml file

docker-compose.yml是一个YAML文件, 它定义了Docker容器在生产环境的表现.

在任何地都可以保存docker-compose.yml文件. 确保你在第二部分已经将映像推送到注册表中, 并且通过替换username/repo:tag来更新.yml.

.yml文件信息

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: username/repo:tag
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "4000:80"
    networks:
      - webnet
networks:
  webnet:

上述的 docker-compose.yml文件告诉Docker做以下工作:

  • 从注册表中拉取下来我们在第二部中上载的映像
  • 运行5个实例作为一个名为web的服务, 限制每个实例最多占用10%的CUP使用率,和50M 内存.
  • 如果有一个实例运行失败,立即重启服务
  • 映射4000端口到web’s 80 端口
  • 指导 web'的容器通过一个叫做webnet的加载均衡网络共享80端口.
  • 定义webnet网络使用默认设置. webnet是一种负载均衡的覆盖网络.

1.5.3.3. Run your new load-balanced app

在我们运行docker stack deploy命令之前, 先运行:

docker swarm init

关于docker swarm init 的介绍将在第四部分.

现在可以运行了. 需要给你的app一个名称, 下面的命令中名称为getstartedlab:

docker stack deploy -c docker-compose.yml getstartedlab

我们的一个服务栈将运行5个容器在我们部署的端口上.

获取服务的 ID

docker service ls

根据app的名字来寻找我们创建的web 服务. 在上面的例子中我们将其命名为getstartedlab.

docker stack services getstartedlab
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
bqpve1djnk0x        getstartedlab_web   replicated          5/5                 username/repo:tag   *:4000->80/tcp

在输出中,将会看家服务的ID, 名称, 模式, 重复数量, 映像, 端口信息

运行在service中的一个容器被称为一个task. tasks 被赋予数字上递增的唯一ID,取决于docker-compose.yml文件中的replicas定义的参数.

列出service中的tasks

docker service ps getstartedlab_web

如果仅仅列出所有系统中的task,没有被服务过滤的和被服务过滤的都会被列出来.

docker container ls -q

你可以在多运行curl -4 https://localhost:4000 (如果由于报错可以试试将https改为http)几次, 或者去在浏览器中多刷新几次.

你会发现容器的ID变了, 证明负载均衡在这5个task中选择.

你可以运行docker stack ps 来查看所有的tasks. 输出如下:

docker stack ps getstartedlab
ID                  NAME                  IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
uwiaw67sc0eh        getstartedlab_web.1   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
sk50xbhmcae7        getstartedlab_web.2   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
c4uuw5i6h02j        getstartedlab_web.3   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
0dyb70ixu25s        getstartedlab_web.4   username/repo:tag   docker-desktop      Running             Running 9 minutes ago                       
aocrb88ap8b0        getstartedlab_web.5   username/repo:tag   docker-desktop      Running             Running 9 minutes ago

1.5.3.4. Sclae the app

你可以通过在docker-compose.yml文件中修改replicas来修改app的规模.
保存修改后,重新运行docker stack deploy 命令:

docker stack deploy -c docker-complose.yml getstartedlab

docker 进行一个现场更新, 不需要先撤销task和kill 容器.

现在运行docker container ls -q 命令来查看部署的实例的配置信息.

1.5.3.5. Take down the app and the swarm

  • 使用docker stack rm命令来拆解app:

    docker stack rm getstartedlab
    
  • 拆解群

    docker swarm leave --force
    

下一个部分将学习在Docker机器集群运行你的app.

1.5.3.6. Recap and cheat sheet(回顾和备忘单)

docker stack ls                                            # List stacks or apps
docker stack deploy -c <composefile> <appname>  # Run the specified Compose file
docker service ls                 # List running services associated with an app
docker service ps <service>                  # List tasks associated with an app
docker inspect <task or container>                   # Inspect task or container
docker container ls -q                                      # List container IDs
docker stack rm <appname>                             # Tear down an application
docker swarm leave --force      # Take down a single node swarm from the manager

1.5.4. 第4部分: Swarms

1.5.4.1. Introduction

第四部分将介绍怎样将你的应用部署到集群, 将它运行在多机器系统中.
荣通过连接多个机器到一个被称为Dockerized的簇,使得多容器和多机器程序构成一个群集.

1.5.4.2. Understanding Swarm clusters

集群是一组计算机运行Docker并且加入到集群中. 在这之后,你可以继续运行你习惯的docker命令, 但是现在他们通过swarm manager(集群管理器)运行在集群中. 集群中的机器可以是实际的机器也可以是虚拟机. 当加入到集群之后他们都被称为node(节点).

集群管理器可以运用几种策略来运行容器, 例如: emptiest node(最空节点):它用容器填充利用率最低的机器;global(全局):它确保每个机器恰好启动一个指定容器的实例. 你可以在Compose file中为集群管理器指定策略.

集群管理器是在一个集群中唯一一个你可以执行你的命令的机器, 或者授权背的机器加入集群作为workers. workers仅仅能够提供生产力并没有权限告诉其他机器自己能做什么.

到目前为止, 你只是使用Docker在你本地的一个主机上. 但是Docker的强大之处在于它可以切换到swarm mode集群模式. 启动集群模式会立即使得当前机器称为集群管理员. 之后,Docker在集群的机器上执行你的任务,而不是只在你的当前主机上.

1.5.4.3. Set up your swarm

集群是由多节点组成, 实际的机器或是虚拟机都可以作为节点.

运行docker swarm init 来打开集群模式并使你当前机器作为集群管理员.

之后在其他机器运行docker swarm join 来使他们加入到集群中.

1.5.4.4. 安装docker-machine

Docker Machine是一个工具,可让你在虚拟主机上安装Docker Engine,并使用docker-machine命令管理主机。docker-machine

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

1.5.4.5. Create a cluster

  1. 首先安装虚拟机 ( install Oracle VirtualBox )[https://www.virtualbox.org/wiki/Downloads].

  2. 使用docker-machine创建一些虚拟机:

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

1.5.4.6. LIST THE VMS AND GET THEIR IP ADDRESSES

现在你创建了两个虚拟机,myvm1,myvm2.

使用一下命令列出虚拟机的IP, 可能需要管理员权限.

docker-machine ls`

以下是输出样例:


$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
myvm1   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce

1.5.4.7. INITIALIZE THE SWARM AND ADD NODES

第一台机器作为管理员, 它执行管理命令和授权其他机器加入集群.

使用docker-machine ssh 发送命令到虚拟机.

使用docker swarm init命令来使myvm1成为集群管理员,输入如下:

$ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"
Swarm initialized: current node <node ID> is now a manager.

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

  docker swarm join \
  --token <token> \
  <myvm ip>:<port>

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
  • 端口2377 和端口 2376

    docker swarm initdocker swarm join使用>端口2377或者使用默认端口.

    docker-machine ls 命令返回机器的IP地址包括端口>2376,改端口是docker守护进程的端口, 请不要使用该端>口做其他事情.

  • 使用SSH有问题? 试试--native-ssh 标签

    Docker 机器可以让你使用原生ssh而不是docker集成的ssh.使用一下命令将会调用机器原生的ssh

    docker-machine --native-ssh ssh myvm1 ...
    

docker swarm init命令包含了预设的docker swarm join 命令, 复制它,然后在myvm2上执行,使myvm2作为一个工作节点加入到集群.

$ docker-machine ssh myvm2 "docker swarm join \
--token <token> \
<ip>:2377"

This node joined a swarm as a worker.

到此,一个简单的集群创建完成.

在管理员机器上运行docker node ls:

$ docker-machine ssh myvm1 "docker node ls"
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
brtu9urxwfd5j0zrmkubhpkbd     myvm2               Ready               Active
rihwohkh3ph38fhillhhb84sk *   myvm1               Ready            

如果想使得一个节点脱离集群, 使用命令:docker swarm leave.

1.5.4.8. 在集群上部署你的应用

有两点需要记住

  • 只有集群管理员节点可以执行Docker 命令
  • workers节点只能进行工作

1.5.4.9. 给集群管理员配置docker-machine脚本

到目前已经学习了:docker-machine ssh命令来控制虚拟机.

另外一种方法是docker-machinne env <maxhine>命令配置当前脚本并与虚拟机上的Docker守护程序进行通信. 在下一部分中该方法的效果更好,因为它允许你使用本地的docker-compose.yml文件配置远程的app.

输入docker-machine env myvm1, 之后复制粘贴并运行输出的最后一行提供的命令,配置shell与集群管理员通信(myvm1).

配置shell的命令根据系统不同而提供不同版本.以下只研究Linux版本

运行docker-machine env myvm1 来获取一条命令,该命令用于配置你的的shell与myvm1进行通信.

$ docker-machine env myvm1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)

接下来运行给出的命令:

eval $(docker-machine env myvm1)

运行docker-machine ls 来查看mymv1是否在运行, *表示激活作态.

$ docker-machine ls
NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
myvm1   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce
myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce

1.5.4.10. 在集群管理员节点上部署app

现在myvm1已经启动, 可以使用它作为集群管理员使用docker stack deploy命令和docker-compose.yml文件来配置你的app,

在集群管理员上使用docker service ps <service_name>命令确认所有的服务被重新部署.

确保当前终端路径中包含docker-compose.yml 文件. 运行以下命令:

docker stack deploy -c docker-compose.yml getstartedlab

现在,app已经成功部署到了集群上.

如果你的image是存储在私有仓库的,那么你需要docker login <your-registry>命令来登录; 另外还要 >--with-registry-auth标志.

docker login registry.example.com

docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab

现在使用和第三部分相同的命令查看task, 方向,servers被分配在了myvm1myvm2上.

$ docker stack ps getstartedlab

ID            NAME                  IMAGE                   NODE   DESIRED STATE
jq2g3qp8nzwx  getstartedlab_web.1   gordon/get-started:part2  myvm1  Running
88wgshobzoxl  getstartedlab_web.2   gordon/get-started:part2  myvm2  Running
vbb1qbkb0o2z  getstartedlab_web.3   gordon/get-started:part2  myvm2  Running
ghii74p9budx  getstartedlab_web.4   gordon/get-started:part2  myvm1  Running
0prmarhavs87  getstartedlab_web.5   gordon/get-started:part2  myvm2  Running
  • 使用docker-machine envdocker-machine ssh 来连接虚拟机.
    • 为了设置你的shell终端与别的机器通信,比如在本次例子中的myvm2,仅需要再次在shell终端中运行docker-machine env命令, 之后运行给出的命令连接myvm2.如果你换了一个没有配置的shell或一个新的shell,你需要重新运行配置指令. 使用docker-machine ls 列出所有的机器, 查看它们的状态,IP的信息,并找出哪一个已经连接.
    • 另外一种选择是,你可以用一下命令包裹Docker命令,docker-machine ssh <machine> "<command>", 该方式的logs会直接记录到VM中,但是不会立即给你在本地机器上的访问通道.
    • 在Mac或者Linux中,你可以使用docker-machine scp <file> <machine>:~来复制文件到其他机器.

1.5.4.11. 访问你的集群

你可以通过myvm1myvm2的IP地址来访问你的app.

运行docker-machine ls 来获取 VMs’ IP地址并且在浏览器中访问他们.

确保集群节点上的7946和4789端口打开:

  • 7946 TCP/UDP 用于容器网络发现
  • 4789 UDP 用于容器入口网络

1.5.4.12. 迭代和扩展你的app

在这里可以做第二部分和第三部分的操作.

扩展app通过更在docker-compose.yml文件.

更在app的行为,通过编辑代码,重构,并推送新的image.

无论在什么情况下,运行docker stack deploy 来部署更改.

你可以使用docker warm join来增加集群的节点. 在运行docker stack deploy 之后, app即可利用新的计算资源.

1.5.4.13. 清除并重启

  1. Stacks and swarms

    你可以撤销stack使用命令:docker stack rm :

    docker stack rm getstartedlab
    

    保留机器或者移除

    • 移除工作节点使用:docker-machine ssh myvm2 "docker swarm leave"
    • 移除管理员节点:docker-machine ssh myvm1 "docker swarm leave --force"
  2. 取消对docker-machine shell的变量设置

    Mac or Linux 上:

    eval $(docker-machine env -u)
    

    在Windows系统上:

    "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env -u | Invoke-Expression
    

    以上命令将会断开与docker-machine创建的虚拟机的连接.

  3. 重启

    如果关闭了本地主机, Docker机器停止执行. 查看Docker机器的状态使用命令:docker-machine ls .

    $ docker-machine ls
    NAME    ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
    myvm1   -        virtualbox   Stopped                 Unknown
    myvm2   -        virtualbox   Stopped                 Unknown
    

    为重启机器,运行:

    docker-machine start <machine-name>
    

    例如:

    $ docker-machine start myvm1
    Starting "myvm1"...
    (myvm1) Check network to re-create if needed...
    (myvm1) Waiting for an IP...
    Machine "myvm1" was started.
    Waiting for SSH to be available...
    Detecting the provisioner...
    Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
    
    $ docker-machine start myvm2
    Starting "myvm2"...
    (myvm2) Check network to re-create if needed...
    (myvm2) Waiting for an IP...
    Machine "myvm2" was started.
    Waiting for SSH to be available...
    Detecting the provisioner...
    Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
    

1.5.4.14. Recap and cheat sheet(回顾和备忘单)


docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1                # View basic information about your node
docker-machine ssh myvm1 "docker node ls"         # List the nodes in your swarm
docker-machine ssh myvm1 "docker node inspect <node ID>"        # Inspect a node
docker-machine ssh myvm1 "docker swarm join-token -q worker"   # View join token
docker-machine ssh myvm1   # Open an SSH session with the VM; type "exit" to end
docker node ls                # View nodes in swarm (while logged on to manager)
docker-machine ssh myvm2 "docker swarm leave"  # Make the worker leave the swarm
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine ls # list VMs, asterisk shows which VM this shell is talking to
docker-machine start myvm1            # Start a VM that is currently not running
docker-machine env myvm1      # show environment variables and command for myvm1
eval $(docker-machine env myvm1)         # Mac command to connect shell to myvm1
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression   # Windows command to connect shell to myvm1
docker stack deploy -c <file> <app>  # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file
docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"   # Deploy an app using ssh (you must have first copied the Compose file to myvm1)
eval $(docker-machine env -u)     # Disconnect shell from VMs, use native docker
docker-machine stop $(docker-machine ls -q)               # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images

1.5.5. 第5部分:Stacks

1.5.5.1. Introduction

该部分是分布式应用程序的顶层:stack. stack是是一组共享依赖,可以相互协调和扩展的一组服务.
一个stack可以定义和协调一个完整的app的功能(尽管复杂的程序可能会需要多个stack).

一些好消息是,从第3部分开始,当您创建Compose文件并使用时,您在技术上一直在使用stack docker stack deploy。但这是在单个主机上运行的单个服务堆栈,不是生产环境所用device方法。在这部分,将使多个服务相互关联,并在多台计算机上运行它们。

1.5.5.2. 增加新服务器并部署

使用docker-compose.yml文件可以很容易的添加服务.
首先增加一个观察者服务, 用它来观察我们的集群怎么调度容器.

  1. 打开docker-compose.yml文件, 使用一下文件替换内容.注意username/repo:tag

    version: "3"
    services:
      web:
        # replace username/repo:tag with your name and image details
        image: username/repo:tag
        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
    networks:
      webnet:
    

    这里新加入了一个名为visualizerweb服务.

    注意这里有两个新的东西:

    • valumes键: 让可视化工具访问Docker的主机套接字文件;
    • placement秘钥: 确保这个服务只能在swarm管理器上运行,但不是一个worker节点.

    该容器是docker开源项目创建的, 用一个图标来展示集群上运行的Docker服务.

  2. 确保shell终端与myvm1在通信状态.

    • 运行docker-machine ls 列出计算机并确保已经连接上myvm1.*表示连接上.
    • 如果没有连接,重新运行docker-machine env myvm1, 详情请看第四部分.
  3. 在管理器上重新运行命令docker stack deplay, 并更新需要更新的任何服务:

    $ docker stack deploy -c docker-compose.yml getstartedlab
    Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)
    Creating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
    
  4. 查看可视化工具

    在compose文件中设置了visualizer的端口的8080, 运行docker-machine ls 获取其IP地址. 然后在浏览器中查看.

1.5.5.3. 存储数据

现在添加Redis数据库来存储aap的数据.

  1. 修改docker-compose.yml文件:

    version: "3"
    services:
      web:
        # replace username/repo:tag with your name and image details
        image: username/repo:tag
        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:
    
    

    在Docker中有一个Redis的官方映像,并拥有一个简短的映像名称:redis. Redis默认使用容器的6379端口暴露给主机.

    最重要的是,在redis的规范中有如下几个事情会使数据在stack的部署之间保持不变:

     - `redis`总是在管理器(管理员节点)上运行,所以它总是使用相同的文件系统.
     - `redis`在主机的任意文件路径下作为数据的存储路径.
    

    总之, 它在主机的物理文件系统中为redis数据创建数据库, 否则, redis将数据存储在容器的文件系统中, 如果重启容器,数据将会丢失.

    "数据的真实来源"包含一下两个内容:

    • 放置Redi服务的主机要确保它所使用的host不会变.
    • 你在主机上创建的存储空间,Redis可以访问. 容器的销毁与新建不会影响到数据.
  2. 在管理员节点上创建一个./data文件夹.

docker-machine ssh myvm1 "mkdir ./data"
  1. 确保shell终端已经配置了和myvm1的通讯.
  • 运行docker-machine ls 来列出并且确认你已经连接上了myvm1,连接上以后会有一个*号.
  • 如果没有连接上,那么运行命令docker-machine env myvm1 , 该命令会给出一条命令,复杂这条命令并运行它.
    • 在Mac或者Linux上,命令如下:
      eval $(docker-machine env myvm1)
      
      在Windows系统上:
      "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
      
  1. 再一次运行docker stack deploy

    docker stack deploy -c docker-compose.yml getstartedlab
    
  2. 运行docker service ls 命令,来查看这三个服务已经在正确的运行.

    docker service ls
    ID                  NAME                       MODE                REPLICAS            IMAGE                             PORTS
    x7uij6xb4foj        getstartedlab_redis        replicated          1/1                 redis:latest                      *:6379->6379/tcp
    n5rvhm52ykq7        getstartedlab_visualizer   replicated          1/1                 dockersamples/visualizer:stable   *:8080->8080/tcp
    mifd433bti1d        getstartedlab_web          replicated          5/5                 gordon/getstarted:latest    *:80->80/tcp
    
    
  3. 在一个节点上访问:http://192.168.99.101,查看访问者数量,现在它被Redis存储,并可以被正确访问.

    另外,在任一个节点的IP加端口号8080访问Docker可视化界面,例如:192.168.99.100:8080.可以看见正在运行的redis服务.

1.5.6. 第六部分:部署应用

1.5.6.1. Introduction

本节将学习Dockerized application的一些选项.

1.5.6.2. 创建一个集群

运行docker swarm init来创建一个集群.

1.5.6.3. 部署APP

运行 docker stack deploy -c docker-compose.yml getstartedlab命令来部署应用在云主机上.

docker stack deploy -c docker-compose.yml getstartedlab

Creating network getstartedlab_webnet
Creating service getstartedlab_web
Creating service getstartedlab_visualizer
Creating service getstartedlab_redis

1.5.6.4. 运行集群命令来验证部署成功

以下为一些必须熟悉的命令:

  • docker node ls 列出集群所有节点.
  • docker service ls 列出所有服务
  • docker service ps <service> 列出一个服务的所有tasks(任务).

1.5.6.5. 在云主机上为服务打开端口

如果app被部署到了云服务器,需要在服务器上打开几个必须的端口.因为一下几个原因:

  • 如果使用许多节点,允许redisweb服务之间通信
  • 允许访问web的任何节点,以便web服务和visualizer可以在浏览器中访问.
  • 允许manager节点的ssh访问.

以下是服务需要暴露的端口:

serviceTpyeProtocolPort
webHTTPTCP80
visualizerHTTPTCP8080
redisTCPTCP6379

1.5.6.6. 跟新和清除

  • 缩放app通过更改docker-compose.yml文件并且使用命令docker stack deploy重新部署
  • 更改app的行为通过更改code,重构,推送新的映像.
  • 拆卸stack,使用命令docker stack rm.例如:
    docker stack rm getstartedlab
    

1.5.6.7. Congratulations!

现在我以及学习完docker的使用,以下为进一步学习内容:

  • Samples 包含了一些流行软件在Docker上的使用.
  • User Guide 包含一个示例,深入解释联网和存储功能
  • Admin Guide 管理Docker化的生成环境的程序
  • Training 官方的Docker课程,它提供了可以实验的学习环境.
  • Blog 官方博客

1.6. Docker设置技巧

1.6.1. 更改image默认存储位置

docker默认的存储位置为/val/lib/docker

更改存储位置

  1. 备份重要的映像
docker save -o 文件名.tar 镜像名
  1. 指定新位置
sudo mkdir /etc/systemd/system/docker.service.d
sudo touch /etc/systemd/system/docker.service.d/docker-overlay.conf #文件名应该可以随便取
sudo vim /etc/systemd/system/docker.service.d/docker-overlay.conf
  1. 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
  1. 恢复备份的映像
docker load -i [docker备份文件.tar]
  1. (可选) 删除旧的/var/lib/docker目录
sudo rm -r /var/lib/docker
原文链接:https://docs.docker.com

docker toolbox在windows下如何为docker命令配置环境变量-爱代码爱编程

docker 1.8版本后,windows下有新版docker承载客户端docker toolbox替代了原来的boot2docker docker toolbox安装后,运行过程中可以配置一系列windows环境变量,让windows命令行终端中也能运行docker命令,就和linux下直接运行docker命令一样的效果,激动吧。但遗憾的是并不傻瓜化,

cannot connect to the docker daemon at unix:///var/run/docker.sock. is the docker daemon running?解决方_jee____的博客-爱代码爱编程

导致这种情况的原因暂时不明,不过经过一翻摸索找到一个解决办法 docker ps Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 解决办法如下: 通过命令查看容器名称 $dock

docker官方文档翻译4_weixin_33744854的博客-爱代码爱编程

原文:https://blog.csdn.net/forezp/article/details/80186178 第四篇:Swarms 准备工作 安装Docker版本1.13或更高版本。安装Docker compose。安装docker machine阅读第1 2 3部分的内容。确保你已发布并推送到注册仓库的friendlyhello镜像。

我的docker笔记(补全ing)_simminongarcia的博客-爱代码爱编程

Introduction Docker helps developers build and ship higher-quality applications, faster." -- What is Docker basics-docker-containers-hypervisors-coreos Referenc

mac安装dockertoolbox和启动docker-爱代码爱编程

为什么80%的码农都做不了架构师?>>>    Mac安装dockertoolbox和启动docker ➜  ~  docker version Client:  Version:      1.8.1  API version:  1.20  Go version:   go1.4.

docker 安装 之 toolbox在windows下安装docker)-爱代码爱编程

为什么80%的码农都做不了架构师?>>>    安装之前先了解下关键概念: 在linux上安装Docker,你的机器即使localhost也是docker主机;在网络中,localhost是指您的计算机。docker主机是容器中在该机器上运行。说白了就是直接安装在linux上,英文翻译真蛋疼。 在Wi

Docker入门--Day13-爱代码爱编程

一:Docker简介 1:Docker是什么 1.1:为什么会有Docker出现        一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验       Docker之所以发展如此迅速

E: 仓库'https://download.docker.com/linux/ubuntu bionic InRelease'将其'Label'值从'Docker EE'修改到了'Docker CE-爱代码爱编程

报错 E: 仓库'https://download.docker.com/linux/ubuntu bionic InRelease'将其'Label'值从'Docker EE'修改到了'Docker CE' N: 为了让这个仓库能够应用,这必须在更新之前显式接受。更多细节请参阅 apt-secure(8) 手册。 解决 sudo apt

Docker Machine安装及入门-爱代码爱编程

安装VMware Workstation Pro 安装Centos7 安装Oracle VM VirtualBox 参考之前的文章: https://blog.csdn.net/xp0406/article/details/104571741 安装docker-machine 版本号更加情况修改,我使用V0.16.0 base=https://git

“usermod:UID‘0‘already exists”-爱代码爱编程

修改run.sh文件部分内容如下: USER_ID="$(id -u)" if [ USER_ID != 0 ]; then USER_ID=1000; else USER_ID=${USER_ID}; fi 完整的run.sh文件如下:   #!/bin/bash set -e # Default settings CUD

Linux学习--Docker学习-爱代码爱编程

容器技术 Docker Images Docker镜像含有启动容器所需要的文件系统及内容,因此用于创建并启动docker容器采用分层构建机制,最底层为bootfs,其之上为rootfs bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后被卸载以节约内存资源rootfs:位于bootfs之上,表现为dock

容器云系列之Docker管理工具Docker Machine-爱代码爱编程

Docker-compose和Docker machine是Docker容器管理的工具,本文简单介绍了Docker machine的使用,加深对Docker管理的理解。 2、Docker Machine 2.1 Docker Machine简介 Docker Machine可以在虚拟主机上安装Docker,并可以使用docker-machine命令来