Docker 入门到进阶

187 阅读10分钟

1、Docker 的安装与卸载(Linux)

参考官网、以下为补充与扩展
# 1、设置 Docker 镜像
# 国外的镜像地址(较慢)
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里云镜像地址(较快)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 2、更新 yum 软件包索引
yum makecache fast
部署 Nginx 小案例
# 搜索 nginx 版本
docker search nginx

# 下载镜像
docker pull nginx

# 启动 nginx(前两步可以忽略)
docker run -d --name nginx01 -p 3344:80 nginx
部署 Tomcat 小案例
# 搜索 tomcat 版本
docker search tomcat

# 下载镜像
docker pull tomcat

# 启动 tomcat(前两步可以忽略)
docker run -d --name tomcat01 -p 3355:80 tomcat

# 本地访问有问题
# 1、缺少 linux 命令
# 2、没有 webapps 文件,阿里云镜像阉割了功能

# 进入容器
docker exec -it tomcat01 /bin/bash
cp -r webapps.list/* webapps # 将 webapps.list 下文件拷贝到 webapps

2、Docker 常用命令

镜像指令

  • docker search mysql -f stars=10 :搜索线上镜像(收藏数大于 10)
    • -f: 过滤条件
  • docker pull:拉取镜像
  • docker images -aq:查看本地镜像
    • -a:显示全部
    • -q:只显示镜像id
    • -f:按照条件过滤
  • docker rmi -f $(dockert images -aq):删除所有镜像

容器指令

  • docker run centos -itd --name centos01 -p 8888:80 /bin/bash|/bin/sh:拉取、运行容器

    • -d:指定容器运行于前台还是后台
    • -i:打开STDIN,用于控制台交互
    • -t, --tty=false, 分配tty设备,该可以支持终端登录
    • -w, --workdir="", 指定容器的工作目录
    • -p, --publish=[], 指定容器暴露的端口
    • -v, --volume=[], 给容器挂载存储卷,挂载到容器的某个目录
    • --net="bridge", 容器网络设置
    • --rm=false, 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
  • docker ps -aq -n=2:查看运行的容器

    • -a, --all:展示所有容器-
    • -f, --filter:过滤条件
    • -n, --last int:展示最近创建的几个容器
    • -l, --latest:展示最后一次创建的容器
    • -q, --quiet:只显示id
    • -s, --size:显示容器大小
  • 启动-停止 docker 状态

    • docker start 容器id
    • docker restart 容器id
    • docker stop 容器id
    • docker kill 容器id
  • 退出容器

    • exit # 停止容器并推出
    • Ctrl + p + q:window 下容器不停止推出
    • control + ⬆️ + p:mac 下容器不停止推出
  • 删除容器

    • docker rm id1 # 删除一个容器
    • docker rm id1 id2 id3 # 删除多个容器
    • docker rm -f $(docker ps -aq) # 删除所有容器

帮助命令

  • docker 命令 --help: 帮助命令
  • docker version: 显示 docker 版本
  • docker info: 显示 docker 的系统信息

其它命令

  • docker exec:进入容器1(进入容器、开启新的终端)
    • docker exec -it tomcat01 /bin/bash|/bin/sh
  • docker attach:进入容器2(进入正在运行容器的终端)
  • docker inspect:查看镜像配置信息
  • docker logs -tf --tail 10 id1:查看日志信息
    • -t # 显示时间戳
    • -f # 显示
    • --tail number # 统计最近 number 条
  • docker top:查看容器进程信息
  • docker top id1

3、制作镜像

docker 方式

# 命令
docker commit -m='描述信息' -a='作者' 容器id 目标镜像:[tag]
# 制作 tomcat 镜像
docker commit -m='制作tomcat镜像' -a='meng' id2 tomcat02:1.0

DockerFile 方式

常用指令
FROM         # 基础镜像
MAINTAINER   # 作者:名字 + 邮箱
RUN          # 构建镜像的时候需要运执行的命令
ADD          # 添加的内容:tomcat 镜像
WORKDIR      # 指定镜像的工作目录
VOLUME       # 指定挂载目录
EXPOSE       # 配置端口
CMD          # 容器启动时运行的命令(控制台 cmd 命令会替换掉配置文件中的 CMD 命令)
ENTRYPOINT   # 容器启动时运行的命令,可追加命令(控制台 cmd 命令会追加到配置文件中的 CMD 命令中)
ONBUILD      # 构建一个被继承的 DockerFile 时就会运行 ONBUILD 的指令
COPY         # 类似 ADD
ENV          # 构建的时候设置环境变量
案例1 - 创建 centos 的 DockerFile
# 1、编写 DockerFile 文件
FROM centos
MAINTAINER meng<123456@aa.com>

# 启动容器进入指定的工作目录
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 下载工具支持 vim、ifconfig 指令
RUN yum -y install vim
RUM yum -y install net-tools

EXPOSE:80

CMD echo $MYPATH
CMD echo /bin/bash


# 2、通过文件构建镜像
# docker build -f dockerfile文件路径 -t 镜像名称:[tag] .
docker build -f DockerFile -t mycentos:1.0.0 .


# 3、测试运行
docker run -it mycentos:1.0.0


# 4、列看镜像的变更历史
docker history
案例2 - 创建 tomcat 的 DockerFile
# 1、准备 tomcat压缩包、jdk压缩包、touch readme.txt介绍文件


# 2、编写 dockerfile 文件(官方命名 Dockerfile,build 会自动找到这个文件)

FROM centos
MAINTAINER meng<123456@aa.com>

# 将同目录下的文件拷贝到容器内
COPY readme.txt /usr/local/readme.txt


# 使用、解压本地镜像(会自动解压)
ADD jdk-8u11-linux-x64.tar.gz /usr/local/  
ADD apache-tomcat-9.0.22.tar.gz /usr/local/

RUN yum -y install vim
RUM yum -y install net-tools

# 启动容器进入指定的工作目录
ENV MYPATH /usr/local  
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_11  
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar  
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22  
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22  
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

# 启动时运行tomcat  
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh" ]  
CMD ["/usr/local/apache-tomcat-9.0.22/bin/catalina.sh","run"] CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out

# 2、通过文件构建镜像
docker build -t diytomcat .


# 3、测试运行
docker run -d -p 9090:8080 --name mydiytomcat -v
/home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-
9.0.22/webapps/test -v
/home/kuangshen/build/tomcat/tomcat9logs/:/usr/local/apache-tomcat-
9.0.22/logs --privileged=true diytomcat


# 4、列看镜像的变更历史
docker history

4、Docker-Compose

实现对 Docker 容器集群的快速编排,配置文件 docker-compose.yml

授权

# chmod +x /usr/local/bin/docker-compose

# 开发环境可以授予最高权限
chmod 777 /usr/local/bin/docker-compose

常用指令

  • 生命周期

    • docker-compose start nginx:启动nignx容器
    • docker-compose stop nginx:停止nignx容器
    • docker-compose pause nginx:暂停nignx容器
    • docker-compose unpause nginx:恢复ningx容器
    • docker-compose restart nginx:重新启动nginx容器
    • docker-compose rm nginx:删除容器(删除前必须关闭容器)
  • 镜像操作

    • docker-compose build nginx:构建镜像
    • docker-compose up docker-compose.yml:启动容器
    • docker-compose down:删除所有nginx容器,镜像
    • docker-compose pull nginx:拉取镜像
    • docker-compose push nginx:推送镜像
  • 查看

    • docker-compose ps:显示所有容器
    • docker-compose logs nginx:查看nginx的日志
    • docker-compose logs -f nginx:查看nginx的实时日志
    • docker-compose events --json nginx:以json的形式输出nginx的docker日
    • docker-compose config -q:验证(docker-compose.yml)文件配置,当配置正确时

yaml 文件

  • version

    • 是必须指定的,而且总是位于文件的第一行。
    • 它定义了 Compose 文件格式(主要是 API)的版本。
    • 注意,version 并非定义 Docker Compose 或 Docker 引擎的版本号。
  • services 用于定义不同的应用服务

    • Docker Compose 会将每个服务部署在各自的容器中。
  • networks 用于指引 Docker 创建新的网络

    • 默认情况下,Docker Compose 会创建 bridge 网络
    • 这是一种单主机网络,只能够实现同一主机上容器的连接
  • volumes 用于指引 Docker 来创建新的卷

部署 mysql 案例
  • docker-compose/docker-compose.mysql.yml
  • docker-compose -f docker-compose.mysql.yml up -d
    • -f :指定自定义yml文件,默认为 docker-compose.yml
    • up -d :启动镜像
  • docker ps
# 指定 docker-compose 版本,应匹配 docker 版本
version: '3'

# services 同时启动多个服务
services:
  
  # 自定义服务名称
  mysql1:
    # 指定 Dockerfile 所在位置(默认为当前目录 docker-compose.yml)
    build: 
      context:./dir # 文件夹所在位置
      dockerfile: myfile # 指定自定义 Dockerfile 文件
    
    # 指定镜像
    image: mysql
    
    # 指定容器名称
    container_name: mysql1
    
    # 指定容器端口
    ports:
    - "8000:3306"
    
    # 挂在目录
    volumes: 
      - /root/data:/var/lib/mysql
      - mysql_logs:/logs
    
    # 设置环境变量
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - SESSION_SECRET #只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据
      
      
    # `restart`:指定容器退出后的重启策略
    # -   `no:` 在任何情况下都不会重启容器
    # -   `always:` 容器总是会重新启动
    # -   `on-failure:` 如果退出代码指示失败错误,则该策略会重新启动容器
    # -   `unless-stopped:` 总是重新启动容器,除非容器停止
    restart: always
    
    # 默认从上倒下启动服务,如果有依赖,会先启动依赖
    depends_on: 
      - redis 
      - mysql  
      
    # 覆盖容器启动后默认执行的命令,即:覆盖 DockerFile 中的`CMD`或第三方镜像的启动命令
    command: "redis-server --appendonly yes" 
    # 或者 
    command: ["redis-server", "--appendonly", "yes"]

部署 web、node、mongodb
version: "3"
services:
  # web服务
  web:
    image: web:1.0
    ports:
      - "8080:80"


  # server 服务
  server:
    image: server:1.0
    ports:
      - "3000:3000"
    depends_on:
      - mongodb
    links: # 不同容器之间网络时不通的,需要使用links
      # mongodb的服务,db:不同容器之间对mongodb的昵称
      - mongodb:db  
       
       
  # mongodb 服务
  mongodb:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456

5、发布镜像:hub.docker.com/signup

发布镜像到 DockerHub
# 1、查看登录命令  
docker login --help  

# 2、登录  
docker login -u kuangshen  
Password:  

# 3、将镜像发布出去  
# docker push 账号/镜像名称|镜像id:[tag]  
docker push meng/diytomcat:1.0

 
# 拒绝:请求的资源访问被拒绝 - 添加 tag 即可  
docker tag 251ca4419332 meng/diytomcat:1.0

# 再次 push, ok  
docker push kuangshen/diytomcat:1.0
发布镜像到阿里云容器
  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间
  4. 创建镜像仓库
  5. 点击进入这个镜像仓库,查看基本信息
  6. 测试推送发布


# 1、登录阿里云  
docker login --username=18225148644 registry.cn- beijing.aliyuncs.com  
Password:  

# 2、设置 tag  
docker tag [ImageId] registry.cn-beijing.aliyuncs.com/bilibili- meng/diytomcat:[版本号]  
# 3、推送命令  
docker push registry.cn-beijing.aliyuncs.com/..../meng- test:[镜像版本号]
  1. 在阿里云镜像仓库查看效果!

6、配置与扩展

配置阿里云加速器
  • 登录阿里云
  • 容器镜像服务
  • 镜像加速器
  • 找到对应的系统,复制命令进行配置进行本地配置
数据卷(目录挂载)

使用命令挂载: -v(volume)

# docker run -v 服务器主机目录:容器目录

# 1、普通挂载:手动定义主机目录
# docker run -v 服务器主机目录:容器目录
docker run -it -v /home/ceshi:/home centos /bin/bash
# 查看目录挂载情况(找到里面的 Mounts)
docker inspect id1


# 2、匿名挂载:无主机目录
docker run -d -p --name nginx01 -v /ect/nginx/ nginx
# 查看所有 volume 的情况(生成的虚拟名称目录)
docker volume ls


# 3、具名挂载:自定义卷名称
docker run -d -p --name nginx02 -v juming-nginx:/ect/nginx/ nginx
# 查看卷的具体位置
docker volume inspect juming-nginx

多个数据库实现数据共享:volumes-form

# 创建数据库 mysql01
docker run -d -p 3310:3306 \
    -v /etc/mysql/conf.d \
    -v /var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql.5.7
    
    
# 创建数据库 mysql02
docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 \
--name mysql01 --volumes-form mysql01 mysql.5.7


# 创建数据库 mysql03
docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 \
--name mysql03 --volumes-form mysql01 mysql.5.7
Docker 网络

Docker 容器网络就很好的利用了 Linux 虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口(veth pair);

image.png

查看网卡:ip addr

image.png

--link (配置 host 绑定 ip)
  • 如果启动 tomcat01、tomcat02、tomcat03 三个容器服务,能不能互相访问?

# 1、使用 tomcat02 直接通过容器名 ping tomcat01,不使用ip 
docker exec -it tomcat02 ping tomcat01 # 发现ping不通


# 2、tomcat03 通过 --link 连接 tomcat02
# 建立连接
docker run -d -P --name tomcat03 --link tomcat02 tomcat

# ping 成功了
docker exec -it tomcat03 ping tomcat02


# 3、原理
# 查看 tomcat03 的 host 文件
docker exec -it tomcat03 cat /etc/hosts

...
127.0.0.1   localhost
172.18.0.3 tomcat02 b80da266a3ad # 发现tomcat2直接被写在这里 172.18.0.4 a3a4a17a2b70
...
自定义网络
  • 查看 docker 网络使用情况:docker network ls

  • 查看容器网络详情::docker network inspect 容器id

  • 网络模式

    • brige:桥接模式(docker 默认)
    • none:不配置网络
    • host:和宿主机共享网络
    • container:容器内网络连通
  • 默认配置网络:默认值 --net bridge

    • docker run -d -P --name tomcat01 [--net bridge] tomcat
      • 1.它是默认的
      • 2.域名访问不通
      • 3.--link 域名通了,但是删了又不行
  • 自定义网络(统一网段互通)

    • docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
    • 使用此网络设置两个容器( 相互ping的通 )
      • docker run -d -P --name tomcat-net-01 --net mynet tomcat
      • docker run -d -P --name tomcat-net-02 --net mynet tomcat
      • docker exec -it tomcat-net-01 ping 192.168.0.3
      • docker exec -it tomcat-net-01 ping tomcat-net-02
  • 网络连通(网卡之间不能打通、网卡和容器之间可以打通)

image.png

  • docker0和自定义网络肯定不通,我们使用自定义网络的好处就是网络隔离。如何让 tomcat-net-01 访问 tomcat1?
# 启动默认的容器,在docker0网络下
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 tomcat


# 启动自定义的容器,在mynet网络下
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat

# 连接一个容器到一个网络
# 1、执行命令后 tomcat01 会被放到 mynet 网络下
# 2、tomcat01 -- 一个容器两个id
docker network connect mynet tomcat01

# 测试
docker exec -it tomcat01 ping tomcat-net-01 # 成功
docker exec -it tomcat02 ping tomcat-net-01 # 失败