Docker笔记

2021-03-31  本文已影响0人  Assassin007

1、Docker简介

1.1 安装

sudo apt install docker-ce

1.2 架构

0MaN8S

2、Docker命令

2.1 服务(守护进程)相关

sudo systemctl start docker
sudo systemctl status docker
sudo systemctl stop docker
sudo systemctl restart docker

2.2 镜像相关

sudo docker images
# 查看具体版本号需要去 hub.docker.com
sudo docker search ubuntu
# 配置阿里云加速:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
sudo vim /etc/docker/daemon.json

{
    "registry-mirrors": ["加速地址"]
}

sudo systemctl daemon-reload
sudo systemctl restart docker

# 拉取镜像
sudo docker pull ubuntu[:版本]
sudo docker rmi ubuntu[:版本]

2.3 容器相关

# 要查看所有包括已停止运行的容器:加上参数 -a
sudo docker ps
# 通过指定镜像版本(不指定默认 latest )创建容器
# -i:在容器上打开一个标准输入接口, -t:创建一个伪终端,一般与 -i 连用来通过伪终端操作容器, 自定义启动命令:如 bash,这会覆盖镜像定义的默认启动命令
sudo docker run -it --name u1 ubuntu[:版本] [自定义启动命令]

# -d:后台创建并启动容器,不会立即进入
# 如果没有一个前台运行的进程,容器是不会保持后台运行的,所以不要随便自定义启动命令
sudo docker run -d --name u1 ubuntu[:版本] [自定义启动命令]
# 只能进入正在运行的容器
sudo docker exec -it u1 bash
sudo docker start u1

# 重启
sudo docker restart u1
sudo docker stop u1
# 不能删除正在运行的容器
sudo docker rm u1
# 查看容器定义信息
sudo docker inspect u1

# 查看容器运行日志
sudo docker logs u1

3、Docker数据卷

3.1 简介

3.2 配置数据卷

# 创建启动容器时,-v 参数设置
# 容器内目录必须是绝对路径,宿主机目录可以相对,但相对的是 /var/lib/docker/volumes/,并不是当前路径
# 目录不存在会自动创建,而文件不存在时会被当成目录创建并挂载
# 可用多个 -v 挂载多个
sudo docker run ... -v 宿主目录(文件):容器内目录(文件) ... --name u1 ubuntu[:版本]

3.3 配置数据卷容器

配置一个专门的容器来挂载数据卷,其他容器挂载这个容器(这时候相当于挂载同一个数据卷)来交换数据

sudo docker run ... -v 宿主目录(文件):容器内目录(文件) ... --name u1 ubuntu[:版本]

# 其他容器挂载 u1
sudo docker run ... --volumes-from u1 --name u2 ubuntu[:版本]
sudo docker run ... --volumes-from u1 --name u3 ubuntu[:版本]

4、Docker应用部署

4.1 搜索并拉取镜像

sudo docker search mysql
sudo docker pull mysql:5.7

4.2 MySQL部署

# 宿主机创建MySQL目录用来存储数据信息
mkdir mysql
cd mysql

# 端口映射 宿主机:容器
sudo docker run -d \
-p 3306:3306 \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=111 \
--name m1 mysql:5.7

4.3 Nginx部署

mkdir nginx
cd nginx

sudo docker run -d \
-p 80:80 \
-v $PWD/conf.d:/etc/nginx/conf.d \
-v $PWD/logs:/var/log/nginx \
--name n1 nginx

5、Docker镜像制作

5.1 Docker镜像原理

0MatC8

5.2 方式一:容器转镜像

这种方式并不常用,因为打包后体积巨大不利于传递。

# 原容器中挂载的目录(文件)不会被提交到镜像
sudo docker commit 容器名(id) 镜像名[:版本号]
# 镜像打包
sudo docker save -o 文件名 镜像名[:版本号]
# 镜像还原
sudo docker load -i 文件名

5.3 方式二:Dockerfile

# 最后的 . 表示当前路径,是上下文目录,构建时会将路径下所有文件发给Docker引擎供 COPY ADD 等命令调用
# 如果配置文件名不为 Dockerfile,可用 -f 指定文件名
sudo docker build -t 新镜像名 .

5.4 Dockerfile常用关键字


6、服务编排(Docker Compose)

微服务架构系统中一般包含多个微服务,每个微服务一般会部署多个实例,如果手动管理工作量就会很大:

服务编排就是按照一定的规则批量管理容器的方法。Docker Compose 是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整生命周期,使用步骤:

6.1 安装

sudo apt install docker-compose

6.2 编排一个 Nginx+Flask+MySQL 项目

mkdir project
cd project
# 创建映射目录
# Flask项目的代码复制到myapp目录下
mkdir -p nginx/conf.d
mkdir -p nginx/log
mkdir -p mysql/data
version: '3'

services:
    # 定义一个容器
    mysql:
        # 可以自定义容器名
        container_name: myapp-mysql
        image: mysql:8
        volumes:
            - ./mysql/data:/var/lib/mysql
        environment:
            MYSQL_ROOT_PASSWORD: qwerdfb
        ports:
            - "3306:3306"
    myapp:
        container_name: myapp-app
        # 可以基于一份Dockerfile制作镜像并创建容器,如果同时指定image会以它命名镜像
        build:
            context: ./myapp
            # 文件名不为Dockerfile时需要指定
            # dockerfile: ./myapp/Dockerfile
        # 暴露端口,并没有与宿主机做映射,只允许被链接容器访问
        expose:
            - "8000"
    nginx:
        container_name: myapp-nginx
        image: nginx
        volumes:
            - ./nginx/conf.d:/etc/nginx/conf.d
            - ./nginx/logs:/var/log/nginx
        ports:
            - "80:80"
server {
        listen  80;  # 监听80端口来自外部的请求
        server_name  _;  # 如果映射了域名,可以代替_

        # 为HTTP规则 / 设置转发
        location / {
            proxy_pass  http://myapp:8000;  # 转发到本地端口
            # 重写一些请求首部
            proxy_set_header  Host  $host;
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto  $scheme;
        }
}
# 如果配置文件名不为 docker-compose.yml,可用 -f 指定文件名
# -d: 后台创建并启动所有容器
sudo docker-compose up
sudo docker-compose ps
# 可通过 sudo docker-compose start 再次启动
sudo docker-compose stop

# 删除所有停止状态的容器
sudo docker-compose rm

# 停止并删除容器,网络
# --rmi all/local (删除compose文件中定义的所有镜像)/(删除镜像名为空的镜像)
# -v 删除已经在compose文件中定义的和匿名的挂载在容器上的数据卷
sudo docker-compose down

7、Docker网络模式

7.1 网络模式及简单使用

安装完 Docker 后,系统自动创建了一个 docker0 网卡以及三种默认网络模式

image-20210421095212280

Docker 安装完成之后,会在宿主机虚拟一个网卡 docker0,容器在默认情况下启动时会从此网段分配一个IP地址,同时 Docker0 是每个容器的默认网关,这样容器之间就能够通过容器的 container-ip 直接通信。
但由于 Docker0 网卡是虚拟出来的,外部网络无法直接进行访问,只能通过端口映射来访问容器,即 docker run 创建容器时候通过 -p 或 -P 参数来启用

上面三种网络模式可以在 docker run 时使用 --net 指定,它们的区别主要是:

7.2 docker-compose中指定网络模式

docker-compose中指定网络模式主要有以下几种场景:

默认情况下,docker-compose 会为我们的应用创建一个网络(网络名称为 docker-compose.yml 所在文件夹名称_default),应用的每个容器都会加入该网络中。这样,容器就可被该网络中的其他容器访问,不仅如此,该容器还能以容器名作为 hostname 被其他容器访问(相当于默认实现了 link)

以下文件为项目创建了两个 docker 网络,假如文件在 myapp 目录下,它们实际的名字分别为 myapp_front 和 myapp_back,这种情况下实现了 nginx 和 db 的网络隔离,它们只能通过 app 通信

version: '3'
services:
  nginx:
    networks:
     - front
  app:
    networks:
     - front
     - back
  db:
    networks:
     - back
networks:
  front:
    driver: bridge
  back:

其实就是设置 services 中的容器未指定 networks 时的默认网络,以下文件效果和未显示声明网络相同(使用默认网络 myapp_default)

version: '3'
services:
  web:
  db:
networks:
  default:
    driver: bridge

如应用容器已经启动,需要单独部署 nginx 服务,可以将它加入到已经存在的应用网络以获得访问应用时更好的网络性能

version: '3'
services:
  nginx:
    networks:
      - myapp_default
networks:
  myapp_default:
    external: true

8、Docker仓库

将自己的应用制作好镜像后,可以上传到 Docker 仓库保存,后面 pull 下来就直接可以使用,Docker 官方仓库 Docker Hub 就提供了镜像托管服务,国内阿里云也有相同服务,此外,我们也可以自己搭建私有仓库来管理团队内部使用的镜像。

8.1 Docker Hub

首先,需要拥有一个 Docker Hub 账户,没有的话先去注册一个吧。进入 Repositories --> Create 来创建一个仓库,一般一个仓库存放一个镜像的所有版本,仓库命名一般为镜像名就好。

# 操作之前需要先登录
sudo docker login --username 用户名

# 打标签将镜像归为某一仓库,版本默认为latest
sudo docker tag 镜像名或id 用户名/仓库名[:版本]
# 上传镜像
sudo docker push 用户名/仓库名[:版本]
# 拉取镜像
# 如果上一步成功且创建的是公开仓库的话这时候应该能搜索到自己的镜像了,当然因为网络情况一般情况下是不成功的
sudo docker pull 用户名/仓库名[:版本]

8.2 阿里云

由于国内网络环境的种种限制,阿里云提供的Docker仓库是一个更好的选择,同样要先有一个阿里云账户,然后去 容器镜像服务 创建仓库,地域选择离自己近的,设置好命名空间,值得一提的是,DockerHub默认以用户名作为命名空间,而阿里云可以创建三个。代码源选择本地仓库,创建好后点击仓库名进入就会有操作指南。

# 同样要先登录先登录,不同的是要加上阿里云站点,注意仓库地域不同站点也不一样
sudo docker login --username 用户名 registry.cn-shanghai.aliyuncs.com

# 打标签
sudo docker tag 镜像名或id registry.cn-shanghai.aliyuncs.com/命名空间/仓库名[:版本]
# 上传镜像
sudo docker push registry.cn-shanghai.aliyuncs.com/命名空间/仓库名[:版本]
# 拉取镜像
sudo docker pull registry.cn-shanghai.aliyuncs.com/命名空间/仓库名[:版本]

8.3 私有仓库

私有仓库其实就是把仓库的服务端部署在自己的服务器上,一般用于一个团队内部使用。

私有仓库它首先也是一个镜像,我们根据这个镜像启动一个容器,然后外部访问这个容器就像前面访问 Docker Hub 或者阿里云的仓库服务一样。

sudo docker pull registry
# 启动容器,容器内对外暴露的端口为 5000
sudo docker run -id --name registry1 -p 5000:5000 registry

# 在 daemon 配置文件内添加一条,让Docker信任此私有仓库
# 如果私有仓库部署在本机,ip为本地地址 127.0.0.1
sudo vim /etc/docker/daemon.json

{"insecure-registries":["部署私有仓库的服务器ip:5000"]}

# 重启docker服务
sudo systemctl restart docker
# 如果私有仓库部署在本机,还需要重启私有仓库容器
sudo docker start registry1

# 接下来使用步骤就和 DockerHub,阿里云大同小异,由于是私有仓库,也就不再需要登录和命名空间了
# 打标签
sudo docker tag 镜像名或id 私有仓库服务器ip:5000/仓库名[:版本]
# 上传镜像
sudo docker push 私有仓库服务器ip:5000/仓库名[:版本]
# 拉取镜像
sudo docker pull 私有仓库服务器ip:5000/仓库名[:版本]
上一篇下一篇

猜你喜欢

热点阅读