docker从入门到精通

docker入门

一、镜像(images)

镜像是轻量的,独立的,可执行包,并且包含了软件运行需要的所有东西,包括代码、运行环境、库、环境变量,配置文件等

二、容器(container)

容器是镜像的一个运行实例——也就是镜像被加载到内存,并且真的被执行之后。默认情况下,容器和主机是完全隔离的,最多也会在配置了的情况下,使用主机的hosts文件和端口

容器使用的基本步骤

1、使用Dockerfile来定义一个容器

​ 对于一些资源的访问,比如网卡、磁盘,在容器里都是虚拟化的,和主机是隔离的,因此,必须把容器内的资源和主机的资源做一个映射;还需要指定你想要把哪些文件copy到容器中(代码)

创建Dockerfile文件,并输入一下代码
# 使用python官方镜像作为镜像的基础
FROM python:2.7-slim

# 设置工作空间为/app
WORKDIR /app

# 把当前目录下的文件拷贝到 容器/app里
ADD . /app

# 安装requirements.txt中指定的依赖
RUN pip install -r requirements.txt

# 开放80端口
EXPOSE 80

# 设置NAME环境变量
ENV NAME World

# 当容器启动时,运行app.py
CMD ["python","app.py"]

2、创建应用app

​ 在Dockerfile同目录下,创建两个文件。因为ADD命令需要把这些拷贝到容器里。而且app.py中的服务器输入端口也正好时80,这是因为配置了EXPOSE而暴露出来

requirements.txt

Flask
Redis
app.py

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

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 = "<h1>can not connect to Redis</h1>"

    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)

3、构建应用

​ 不需要安装python,也不需要安装requirements.txt中的任何依赖包

​ 执行构建命令,创建一个自己的dockerfile镜像


#将当前文件的所有文件构建成friendhello的镜像文件
docker build -t friendhello .

4、运行自定义应用

​ 运行时需要映射端口号


#使用-p参数将容器内80端口映射到主机的5000端口
docker run -p 5000:80 friendhello

#后台运行docker应用
docker run -d -p 5000:80 friendhello

5、结束应用进程


#查询容器ID
docker ps

#关闭docker
docker stop id

6、登录docker


docker login

#根据要求填写用户名和密码

7、给镜像打标签


docker tag friendhello smiletosunshine/test:hello
    
docker images
    
# 打标签语法格式:
    docker tag 镜像image名 用户名/仓库名:标签
注意:

​ 如果给镜像打标签的时候,没有加 :tag,那么默认镜像的标签为 :latest

8、将镜像推送至远程终端


docker push smiletosunshine/test:hello

# 语法格式
    docker push 用户吗/仓库名:标签

9、执行远程应用


docker run -d -p 5000:80 smiletosunshine/test:hello
        
# 语法格式
    docker run -d -p 映射端口:应用端口 用户名/仓库名:标签

10、拉取远程镜像


docker pull smiletosunshine/test:hello
注意:

​ 如果run的时候,没有找到image,会自动从官网pull

11、删除镜像


#删除镜像
docker rmi -f 镜像id

#强制删除运行中容器
docker rm -f 容器id

三、服务(services)

​ 服务就是一个应用中的容器。“一个服务只运行一个镜像,但是,他会编排镜像的运行方式——使用哪个端口,需要多少个实例才能满足需求”

​ 伸缩一个服务就是改变这个服务的运行容器数量

1、使用docker-compose.yml文件控制docker容器的行为

# 只有version>=3.x才能使用docker stack deploy命令
version: "3"
services:
  web:
    # 拉取镜像
    image: smiletosunshine/test:part1
    deploy:
      # 运行5个实例
      replicas: 5
      resources:
        # 限制CPU使用率
        limits:
          cpus: "0.1"
          memory: 50M
      # 自动重启容器
      restart_policy:
        condition: on-failure
    # 端口映射
    ports:
      - "80:80"
    # 设置负载均衡网络
    networks:
      - webnet
networks:
  webnet:
   
# 注意:缩进不能错
上述的docker-compose.yml定义了docker的行为:

​ 1、从注册中心拉取镜像

​ 2、运行5个实例作为服务web,并且限制每个实例都CPU使用率最多只能到10%,内存最多占用50M

​ 3、容器启动失败则重启

​ 4、把主机的80端口映射到web服务器的8000端口

​ 5、指示web服务器的所有容器通过一个负载均衡的网络webnet来共享80端口

​ 6、把webnet网络作为默认网络设置

2、运行负载均衡

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

#语法格式
docker stack deploy -c yml文件 自定的应用名
注意:

​ 在运行docker stack deploy之前,需要使用docker swarm init初始化,否则会报“this node is not a swarm manager”

3、伸缩应用

修改docker-compose.yml中的replicas数量,保存后,运行


docker stack deploy -c docker-compose.yml getstartedlab
注意:

​ docker是自动更新的,不需要手动kill

4、移除应用

#移除应用
docker stack rm getstartedlab

#关闭swarm
docker swarm leave --force

四、集群(swarm)

​ swarm就是一个运行docker的集群。可以使用docker来对swarm manager下命令,从而控制这个集群,集群中的机器可以是真实的物理机,也可以是虚拟机。

swarm manager策略:

在compose文件中指定swarm manager策略:

​ 最空节点:选择使用率最低的节点来运行容器

​ 全局策略:每个节点至少有一个镜像的容器

1、配置swarm

​ 执行docker swarm init来开启一个swarm节点,并且把当前执行命令的节点作为管理节点,然后在其他机器上执行docker swarm join来加入这个swarm集群

2、使用虚拟机来完成swarm集群的配置

# 创建两个虚拟机,分别为myvm1和myvm2

docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
3、设置管理节点和工作节点

# 把myvm1设为管理节点

docker-machine ssh myvm1 "docker swarm init"
注意:

​ 执行失败,提示要加—advertise-addr

​ 使用docker-machine ls查看虚拟机,然后拷贝myvm1的ip,指定端口2377

​ 例如:


docker-machine ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100:2377"

初始化成功之后会返回一个提示信息,拷贝命令,然后去myvm2中执行


docker-machine ssh myvm2 "docker swarm join \--token <token> \<ip>:<port>"
注意:

​ 配置工作节点时的 \ 不能丢,必须加上,否则报错,且\前加空格,\后不可加空格

4、查看集群中的所有节点

# 登录管理节点之中,只有管理节点才可以执行docker命令
docker-machine ssh myvm1

docker node ls
5、退出,回到原机器

exit
6、部署应用

# 使用scp上传yml文件至管理节点
docker-machine scp docker-compose.yml myvm1:~
   
# 部署应用
docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
7、查看部署后的应用容器

docker-machine ssh myvm1 "docker stack ps getstartedlab"
8、访问集群

# 查询ip
docker-machine ls

通过myvm1和myvm2中的任意一个ip均可访问,因为整个集群内的网络是共享的

9、伸缩应用

# 修改docker-compose.yml文件
# 执行docker stack deploy
10、清除应用

# 清除应用
docker-machine ssh myvm1 "docker stack rm getstartedlab"

# 让工作节点脱离swarm集群
docker-machine ssh myvm2 "docker swarm leave"

# 关闭管理节点
docker-machine ssh myvm1 "docker swarm leave --force"

五、堆栈(stack)

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
networks:
  webnet:
说明:

​ 添加一个与web服务平级的服务visualizer。volumes,为可视化服务添加访问主机socket文件的权限;placement,确保服务只运行在swarm的管理节点上。

2、编辑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:
      - ./data:/data
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
networks:
  webnet:
说明:

​ 要保证redis只会运行在管理节点上,这样就可以让redis运行在同一个文件系统上

​ redis访问的文件路径时一样的,这样就可以从这个路径来读取和存储文件

3、在管理节点上创建redis的数据持久化路径

docker-machine ssh myvm1 "mkdir ./data"
3、上传新的docker-compose.yml文件
docker-machine scp docker-compose.yml myvm1:~


4、部署应用
docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"


5、查询结果
docker-machine ps


浏览器输入ip

猜你喜欢

转载自blog.csdn.net/Misaki_root/article/details/80240157