Administrator
发布于 2026-05-17 / 16 阅读

Docker

简介

  • 开源的应用容器引擎,基于Go语言

  • 完全隔离的沙箱机制,类似app之间的关系

  • 重要的是性能开销极低

  • 程序简化

  • docker镜像中包含环境,服务环境搭建简单

应用场景

  1. web自动打包发布

  2. 自动化测试

  3. 在服务型环境中部署,调整 应用

Docker引擎

  1. 包含以下组件的客户端服务器应用程序
  • 一种服务器,一种称为守护进程并长时间运行的程序

  • REST API 用于指定程序可以用来与守护进程通信的接口

  • 一个有命令行界面的CLI工具的客户端

Docker系统架构

  1. 使用客户端-服务器架构模式,使用远程api来管理和创建Docker容器

  2. Docker容器通过Docker镜像来创建

  3. 关系:容器---》对象,镜像------》类

  4. 镜像封装了基本的属性

  5. 真正操作的是容器,

  6. docker pull ---->守护进程---》创建两个容器------》本机存在镜像的时候直接创建,否则到docker库下载

Docker安装

  1. 可以安装在windwos,mac,linux

  2. 前提条件

  3. 若为linux只适用于64位

  4. linux内核要大于3.10

  5. https://www.dean0731.cn/archives/582/

第一个Docker应用程序


# 从网上下载ubuntu15.10 的镜像,创建一个容器 ,使用容器打印 “hello docker"

docker run ubuntu:15.10 /bin/echo "hello Docker"

docker images

docker ps

docker rm containerID


# 用主线程的交互式容器,即可进入Ubuntu容器 root命令行

docker run -it ubuntu:15.10 /bin/bash

后台运行 -d表示在后台

docker run -d ubuntu:15.10 /bin/bash -c "while true:do echo hello docker;sleep 1;done"


# 查看容器日志,加参数 -f可动态查看

docker logs containerId

docker stop containerId

# 适用bash与正在运行的容器进行交互

docker exec -it containerId /bin/bash

docker COMMAND --help

运行web容器


# 在一个完整的操作系统上运行python程序  

# -P:表示把容器的端口映射到宿主机,宿主机随机一个端口映射到容器

# 镜像为training/webapp    

# 它是一个flask程序  运行命令python app.py

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

# 可以指定访问端口 宿主机4000,容器5000

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

# 查看容器中的进程

docker top containerId

docker top names

# 查看容器状态:json字符格式

docker inspect


# 出现一个新的image,与上个同名,tag不同,        设置镜像标签

docker tag containerId imageName:newTag

docker 安装后会产生一个虚拟网卡,mac等,容器产生的Ip都是基于虚拟网卡的

Docker镜像管理

若使用的镜像不存在会从 Docker Hub 下载


docker pull tomcat

docker pull tomcat:8.5.49-jdk11-openjdkv

# 镜像,默认获取最新版本,也可以指定版本获取

# 镜像,一般选择官方的,使用docker pull name 获取

# starts 表示的是使用量,可作为评价标准 

docker search tomcat


# 创建镜像from容器

docker commit -m="has update" -a="userName" containerId  newImageName:Tag(随便)

# Dockerfile创建镜像

mkdir myUbuntu

cd myUbuntu

vi Dockerfile #(名字不要更改)

    FROM ubuntu:15.10 # 系统

    MAINTAINER your-email

    COPY test.txt /home # 将宿主机的文件test.txt copy 到镜像的home下

    RUN /bin/bash -c "Hello world" # 指定镜像默认执行的命令

    CMD ["/bin/echo","this is param1"] # 文件中只能有一个cmd,有多个会只执行第一个

    WORKDIR /home # 指定默认的工作目录

    EXPOSE 80 # 暴露端口

    EXPOSE 8080

docker build -t yourImageName . # 在当前目录查找dockerfile 为改文件的镜像命名

Docker实例教程


# 使用docker 后台运行tomcat容器 并做端口映射,并修改容器的默认名字为tomcat,

docker run --name tomcat -p 8080:8080 -d tomcat

# 若要在容器内tomcat 部署程序,交互式进入,写自己的html即可


docker pull mysql # 拉去mysql 镜像

docker run -p 3306:3306 -name mysql \

-v /usr/local/deoker/mysql/conf:/etc/mysql \ # 映射宿主机目录到容器目录

-v /usr/local/docker/mysql/logs:/val/log/mysql \ # -v 数据卷

-v /usr/local/docker/mysql/data:/var/lib/mysql \

-e MYSQL_ROOT_PASSWORD=123456 \ # -e 指定环境边变量

-d mysql

# 若以后要重新运行时,密码变更了,需要删除宿主机下原来的数据卷,否则会不生效,还使用原来的配置。


vim Dockerfile

    FROM tomcat

    MAINTAINER email

    ADD xxx.war /usr/local/tomcat/webapps/xxx.war # 添加war包到容器

docker build -t name . # 构建镜像

docker run -d -p 8080:8080 imageName

# 本方式是直接将war打入本镜像,比较麻烦,可使用数据卷解决

数据卷

  • 绕过拷贝写,修改容器内容相当于直接修改宿主机内容,性能高

  • 不需要在docker commit 打包进镜像文件

  • 宿主,容器,容器之间共享文件

  • 创建数据卷


docker run -d -P -v /webapps training/webapps python app.py

# 将tomcat容器的目录映射到宿主目录,即时原容器目录有内容也不可用

docker run -name tomcat1 -d -p 8080:8080 -v  /usr/local/docker/tomcat/share/webapps:/usr/local/tomcat/webapps tomcat

# 或

dockerfile中指定   VOLUME /var/lib/test

  • 备份数据卷

docker run -p 3306:3306 -name mysql \

-v /usr/local/deoker/mysql/conf:/etc/mysql \ 

-v /usr/local/docker/mysql/logs:/val/log/mysql \ 

-v /usr/local/docker/mysql/data:/var/lib/mysql \

-e MYSQL_ROOT_PASSWORD=123456 \ 

-d mysql

# 启动数据库

# 1. 连接容器内数据库,做出修改

# 2. 进入宿主机的数据卷,直接备份docker/mysql目录即可   tar -zcvf backup.tar.gz .

# 3. 恢复数据卷,其重新的容器时,挂载备份的文件即可

Docker Compose

  • 简化docker操作的工具,安装docker-compose

curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

# 或直接下载上传即可,重命名为docker-compose,放入环境变量目录

chown -R root:root docker-compose

chmod +x docker-compose

# 官网那个可能慢

curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m`>/usr/local/docker-compose

  • docker-compose 使用

# 启用tomca容器

# 原始方法:docker run .......

# docker-compose

mkdir tomcat;cd tomcat

vim docker-compose.yml # yml 语言

 version: "3" # compose的版本号决定

 services:

  tomcat: # 服务名字,可变的

   restart:always

   image:tomcat

   container_name:tomcat

   ports:

     - "8080:8080"

docker-compose up # 此时是主线程启动

docker-compose down # 停止,并删除

docker-compose up -d # 后台运行 必须在docker-compose.yml所在的目录


version: "3"

services:

 tomcat:

  restart:always

  image:tomcat

  container_name:tomcat

  ports:

   - "8080:8080"

  volumes:

   - "/usr/local/docker/tomcat/webapps/test:/usr/local/tomcat/webapps/test"

  environment:

   TZ: Asia/Shanghai


# mysql

version: "3"

services:

 mysql:

  restart: always

  image:mysql

  container_name:mysql

  port:

   - 3306:3306

   environment:

    TZ:Asia/Shanghai

    MYSQL_ROOT_PASSWORD:123456

   command:

    --character-set-server=utf8mb4

    --collation-server=utf8mb4_general_ci

    --explicit_defaults_for_timestamp=true

    --lower_case_table_name=1

    --max_allowed_packet=128M

    --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBST\

    ITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATA,ERROR_FOR_DIVISION_BY_ZERO"

   volumes:

    - mysql-data:/var/lib/mysql

  volumes:

   mysql-data: # docker安装目录/volumes/下创建mysql_mysql-data文件夹作为映射

   # /var/lib/docker/volumes/mysql_mysql-data


 version: 3

     services:

      tomcat:

       restart:always

       image:tomcat

       container_name:tomcat

       ports:

        - 8080:8080

       volumes:

        - /usr/local/docker/project/webapps/:/usr/local/tomcat/webapps/

       environment:

        TZ: Asia/Shanghai

      mysql:

       restart: always

       image:mysql

       container_name:mysql

       port:

        - "3306:3306"

       environment:

        TZ:Asia/Shanghai

        MYSQL_ROOT_PASSWORD:123456

       command:

        --character-set-server=utf8mb4

        --collation-server=utf8mb4_general_ci

        --explicit_defaults_for_timestamp=true

        --lower_case_table_name=1

        --max_allowed_packet=128M

        --sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SU\

      BSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATA,ERROR_FOR_DIVISION_BY_ZERO"

       volumes:

        - mysql-data:/var/lib/mysql

     volumes:

      mysql-data:

  • 项目部署

image-20200910201125247


# 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)


# requirements.txt

flask

redis


# 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

EXPOSE 5000

COPY . .

CMD ["flask", "run"]


# docker-compose.yml

version: '3'

services:

web:

build: .   # 使用当前Dockerfile构建镜像

ports:

  - "5000:5000"

redis:

image: "redis:alpine"  # 使用现成镜像


# build

docker-compose build

# 启动

docker-compose up -d

  • 创建网络

  • 执行docker-compose.yml

  • 启动服务

  • 就是里面的镜像

  • 默认服务名:文件名_服务名__num(运行实例个数)

  • 网络

  • docker network ls

  • 通过compose启动,就会生成网络,因此项目中网络都是一个

  • 访问时不用ip,使用服务名,更简洁,在springboot配置文件中 spring.redis.host=redis


version: "3.8"

services:

redis: # 服务

image: redis:alpine

ports:

  - "6379"

networks:

  - frontend

deploy:

  replicas: 2

  update_config:

    parallelism: 2

    delay: 10s

  restart_policy:

    condition: on-failure

db: # 服务

image: postgres:9.4

volumes:

  - db-data:/var/lib/postgresql/data

networks:

  - backend

deploy:

  placement:

    max_replicas_per_node: 1

    constraints:

      - "node.role==manager"

vote:

image: dockersamples/examplevotingapp_vote:before

ports:

  - "5000:80"

networks:

  - frontend

depends_on:

  - redis

deploy:

  replicas: 2

  update_config:

    parallelism: 2

  restart_policy:

    condition: on-failure

result:

image: dockersamples/examplevotingapp_result:before

ports:

  - "5001:80"

networks:

  - backend

depends_on:

  - db

deploy:

  replicas: 1

  update_config:

    parallelism: 2

    delay: 10s

  restart_policy:

    condition: on-failure

worker:

image: dockersamples/examplevotingapp_worker

networks:

  - frontend

  - backend

deploy:

  mode: replicated

  replicas: 1

  labels: [APP=VOTING]

  restart_policy:

    condition: on-failure

    delay: 10s

    max_attempts: 3

    window: 120s

  placement:

    constraints:

      - "node.role==manager"

visualizer:

image: dockersamples/visualizer:stable

ports:

  - "8080:8080"

stop_grace_period: 1m30s

volumes:

  - "/var/run/docker.sock:/var/run/docker.sock"

deploy:

  placement:

    constraints:

      - "node.role==manager"

networks:

frontend:

backend:

volumes:

db-data:


# java dockerfile例子

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8888"]

EXPOSE 8888

ENTRYPOINT ["java","-jar","/app.jar"]


version: '3.8'

services:

javaservice:

    build: .

    image: javaservice

    depends_on:

        - redis

    ports:

        - "8888:8888"

redis:

    image: "redis:alpine"

集群 Docker Swarm

  • 集群方式部署,主机更多的时候使用k8s

  • xshell命令同步操作安装docker

  • 工作模式

image-20200910213320141


# swarm 集群初始化

docker swarm init --advertise-addr ip1 # 初始化节点 默认是lader,是管理节点

# 令牌生成

docker swarm join-token worker

docker swarm join-token manager

# 加入集群work。manager使用令牌加入

# worker,manager:Reachable,loader

# 一般情况管理节点大于等于3个,此时有损坏的开可以使用,若2管理节点,损坏一个后就不能使用了,即最少2个管理可使用,否则就会docker集群就不能使用了,raft协议:保证大多数节点存活

# docker node ls 查看节点

# docker swarm leave 离开集群

docker service,之前的集群,不能动态扩容,缩容

  • 容器---》服务--》副本

# nginx 集群

# 服务启动 滚动更新,扩容,缩容,docker run不可以

# 会随机在worker启动

docker service -p 8888:80 --name my_nginx nginx

# 查看服务信息

docker service ps my_nginx

# 查看服务列表

docker service ls

# my_nginx 创建副本

docker service update --relipcas 3 my_nginx

# 作用同上

docker service scale my_nginx=3

# 访问时访问集群中任何一个都可以 https://ip1:8888,https://ip2:8888,即使ip2没有服务,但它在集群中

# 缩小

docker service update --relipcas 1 my_nginx

# 移除服务

docker service rm my_nginx

扩展:网络模式

overlay:集群中不同主机上的docker是不能ping的,此模式使用虚拟ip,完成此功能

imgress:overlay的进一步开发,有负载均衡作用

Docker stack


# 单机docker-compose

docker-compose up -d

# 集群docker stack

docker stack deploy

# 也是基于yaml文件,与compose格式类似

Docker secret

统一秘钥管理

Docker config

统一配置管理

扩展到k8s

  • 云原生时代,直接云端下载应用,购买服务器,部署k8s即可使用

  • go语言,天生的并发语言,docker,kvs,v8等都是go开发的


评论