Docker++:从 0 到 1 学习Docker(笔记)

本篇文章有点长 ... 知识点如下:下 ↓ ↓ ↓

  ~ 初识 Docker 

  ~ Docker 命令

  ~ Docker 容器的数据卷

  ~ Docker 应用部署

  ~ Dockerfile

  ~ Docker 服务编排

  ~ Docker 私有仓库

  ~ Docker相关概念

 


 

初始 Docker:↓ ↓ ↓

我们写的代码会接触到好几个环境:开发环境、测试环境以及生产环境:

Docker 概念::↓ ↓ ↓

· Docker 是一个开源的应用容器引擎

· 诞生于2013年初,基于Go语言实现,dotCloud 公司出品(后改名为 Docker Inc)

· Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。

· 荣发起完全使用沙箱机制,互相隔离

· 容器性能开销极低

· Docker 从 17.03 版本后分为 CE (Community Edition:社区版)和 EE (Enterprise Edition:企业版)

总之:docker是一种容器技术,解决软件跨环境迁移问题

安装 Docker:↓ ↓ ↓

Docker 可以运行在 MAC、Windows、CentOS、UBUNTU 等操作系统上,本次演示基于 CentOS 7 安装

Docker 官网:https://www.docker.com

安装步骤如下:

复制代码
1、yum 包更新到最新
yum update

2、安装需要的软件包,yum-utils 提供 yum-comfig-manager功能,另外两个是devicemapper驱动依赖的。
yum install -y yum-utils device-mapper-persistent-data lvm2

3、设置yum 源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

4、安装docker,出现输入的界面都按 y
yum install -y docker-ce

5、查看docker版本,验证是否验证成功
docker -v
复制代码

Docker 架构:↓ ↓ ↓

配置 Docker 镜像加速器:↓ ↓ ↓

默认情况下,将来从docker hub (https://hub.docker.com/)上下载docker镜像,太慢。一般都会配置镜像加速器:

~ USTC:中科大镜像加速器(https://docker.mirrors.ustc.edu.cn)

~ 阿里云
~ 网易云

~ 腾讯云

本次采用 阿里云 镜像加速器... 需要登录自己的阿里云账号 进行获取加速器地址,因为每个人的地址都不一样。

Docker 服务常规相关命令:↓ ↓ ↓

复制代码
1、启动 docker 服务
systemctl start docker

2、查看状态
systemctl status docker

3、停止 docker 服务
systemctl stop docker

4、重启 docker 服务
systemctl restart docker

5、开机启动 docker 服务
systemctl enable docker
复制代码

Docker 镜像常规相关命令:↓ ↓ ↓

复制代码
1、查看镜像列表
docker images

2、镜像搜索
docker search redis

3、下载镜像
docker pull redis:3.2 //:3.2 指的是版本号、默认不写版本为 latest

4、删除镜像
docker rmi 镜像ID

5、查询所有镜像ID
docker images -q

6、删除所有镜像
docker rmi `docker images -q`
复制代码

Docker 容器常规相关命令:↓ ↓ ↓

复制代码
1、查看运行容器
docker ps
查看历史容器(运行与没有运行的)
docker ps -a
2、创建容器
docker run -it --name=c1 centos:7 /bin/bach
# -i : 表示(没有客户端连接)一直运行着
# t : 表示给容器分配一个尾的终端
# -id: 表示后台运行
# --name : 给容器取一个名字
# centos:7 : 根据什么镜像创建容器
# /bin/bach : 进入容器后的初始化指令
3、进入容器
docker exec -it 容器名称 /bin/bash
4、启动容器
  docker start 容器名称
5、停止容器
docker stop 容器名称
6、删除容器
docker rm 容器名称|容器ID
docker rm `docker ps -aq`
7、查看容器信息
docker inspect 容器名称

8、已存在容器增加挂载目录
docker run -v /path/to/mount:/path/in/container --name container_name image_name
使用docker run命令重新启动容器,并通过-v参数指定要挂载的目录。将/path/to/mount替换为主机上的目录,/path/in/container替换为容器内的目录,container_name替换为容器的名称,image_name替换为容器的镜像名称
复制代码

Docker 容器的数据卷:↓ ↓ ↓

数据卷概念及作用:

思考:

~ Docker 容器删除后,在容器中产生的数据还在吗?(肯定不在了)

~ Docker 容器和外部机器可以直接交换文件吗?(外部主机与宿主机可以通信;与容器无法通信)

~ 容器之间想要进行数据交互?

数据卷:

~ 数据卷是宿主机中的一个目录或文件

~ 当容器目录和数据卷目录绑定后,对方的修改会立即同步

~ 一个数据卷可以被多个容器同时挂载

有了数据卷之后就可以解决上边三个问题了。

数据卷作用:

~ 容器数据持久化

~ 外部机器和容器间接通信

~ 容器之间数据交换

配置数据卷:

1、创建启动容器时,使用 -v 参数 设置数据卷
docker run ... -v 宿主机目录(文件):容器内目录(文件)...

  docker run -id --name=c1 -v /opt/docker/data:/opt/docker/data_c1 centos:7 /bin/bash

 注意事项:

~ 目录必须是绝对路径

~ 如果目录不存在,则会自动创建

~ 可以挂载多个数据卷

Docker 数据卷容器:↓ ↓ ↓

问题分析:多容器进行数据交互:(两种方式)

  ~ 多个容器挂载同一个数据卷

     ~ 数据卷容器

加入:c3 容器卷挂掉之后 还可以通过数据卷继续通讯

复制代码
1、创建启动C3数据卷容器,使用 -v 参数 设置数据卷
docker run -it --name=c3 -v /volume centos:7 /bin/bash
-v /volume:容器目录  冒号左边的不写会默认分配一个 

创建完成后会在宿主机上自动分配一个数据卷目录。

2、创建启动 c1 c2 容器,使用 --volumes-from 参数 设置数据卷
docker run -it --name=c1 --volumes-from c3 centos:7 /bin/bash
docker run -it --name=c2 --volumes-from c3 centos:7 /bin/bash
复制代码

在c3进行操作 c1 、c2 也会做出相应的操作。

Docker 应用部署:↓ ↓ ↓

~ MySQL 部署

需求如下:

  在docker容器中部署MySQL,并通过外部MySQL客户端操作MySQL Server。

步骤如下:

  1、搜索MySQL镜像

  2、拉取MySQL镜像

  3、创建容器

  4、操作内容中的MySQL

需求分析:

  现在我们将实现,使用客户端连接容器中的MySQL,上边已经说过 容器与外界是不通讯的,那该怎么办?

~ 容器内的网络服务和外部机器不能直接通信

但是外部机器可以访问宿主机、而且我们的宿主机和容器是可以通讯的。

那么我们就可以把宿主机的端口 与 容器内服务端口 进行一个映射绑定。

外部机器访问宿主机的该端口,从而间接访问容器的服务。

开始部署:↓

复制代码
1、搜索MySQL镜像
docker search mysql
2、拉取MySQL镜像
docker pull mysql:5.6
3、创建容器,设置端口映射,目录映射
# 在 /opt目录下创建mysql目录用于存储MySQL数据信息
  mkdir /opt/mysql_1
cd /opt/mysql_1
-----------------------------------------------------------
docker run -id \
-p 3307:3306 \
--name=c_mysql \
-v $PWD/conf:/etc/mysql/conf.d \
-v $PWD/logs:/logs \
-v $PWD/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.6
复制代码

参数说明:

$pwd 表示当前所在目录

-p:3307:3306                             将容器的3306端口映射到宿主机的3307端口

-v $PWD/conf:/etc/mysql/conf.d  将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf 配置目录

-v $PWD/logs:logs                       将主机当前目录下的logs 目录挂载到容器的/logs 日志目录

-v $PWD/data:var/lib/mysql          将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录

-e MYSQL_ROOT_PASSWORD=123456   初始化 root 用户的密码。

切换到容器中:执行 mysql -uroot -p123456  能连接的话说明就成功了。

~ Tomcat 部署

前序步骤和上述一样

复制代码
1、创建容器,设置端口映射、目录映射
#在 /opt 目录下创建tomcat目录用于存储tomcat数据信息
mkdir /opt/tomcat
cd /opt/tomcat

创建tomcat容器
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD/webapps/:/usr/local/tomcat/webapps/ \
tomcat

mkdir /opt/tomcat/webapps/ROOT
vim index.html

#为什么会创建ROOT那 因为Tomcat特性默认回去访问 ROOT 下的资源

默认自动启动
复制代码

参数说明:

-p : 8080:8080  将容器的8080端口映射到主机的8080端口

-v $pwd/webapps:/user/local/tomcat/webapps   将主机中当前目录挂载到容器的 webapps

遇到的问题(换个脑子):传送门 → → 

1、docker运行Tomcat后访问首页报404 (永久解决方式)

~ Nginx 部署:

复制代码
# 在 /opt 目录下创建nginx目录用于存储nginx数据信息
mkdir /opt/nginx
cd /opt/nginx
mkdir conf
cd conf
#在/opt/nginx/conf/ 下创建nginx.conf 文件,粘贴下面内容
复制代码
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            alias   /usr/share/nginx/html/;
            autoindex on;                 # 打开目录浏览功能
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
复制代码

 

复制代码
docker run -id --name=c_nginx \
-p 80:80 \
-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf \
-v $PWD/logs/:/var/log/nginx/ \
-v $PWD/html/:/usr/share/nginx/html/ \
nginx

一系列测试 ...

~ Redis 部署:与上述操作一个道理

复制代码
1、创建容器,设置端口映射
docker run -id --name=c_redis -p 6379:6379 redis:5.0

2、使用外部机器连接redis
./redis-cli.exe -h ip -p 6379

docker run -d -p 6379:6379 --name c_redis -v $PWD/conf/redis.conf:/etc/redis/redis.conf -v $PWD/data:/data --restart=always redis:5.0 redis-server /etc/redis/redis.conf --appendonly yes
复制代码

DockerFile 镜像原理:↓ ↓ ↓

知识点:

  ~ Docker 镜像原理

  ~ DockerFile 概念及作用

  ~ DockerFile 关键字

  ~ 案例

思考:来自灵魂三问 ...

  ~ Docker 镜像本质是什么?

    解: 是一个分层文件系统

  ~ Docker 中一个 centos 镜像为什么只有200M,而一个centos 操作系统的 iso 文件要几个G?

              解:centos 的 iso 镜像文件包含 bootfs 和 rootfs ,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其它镜像层

  ~ Docker 中一个 tomcat 镜像为什么有 500M,而一个 tomcat 安装包只有 70多 MB ?

    解:由于docker中镜像是分层的,tomcat 虽然只有 70多M,但他需要依赖于镜像和基础镜像,

                      所以整个对外暴露的tomcat镜像大小500多M。

镜像原理:↓

操作系统的组成部分:

· 进程调度子系统

· 进程通讯子系统

· 内存管理子系统

· 设备管理子系统

· 网络通信子系统

· 作业控制子系统

· 文件设备子系统  ↓

Linux 文件系统由 bootfs 和 rootfs 两部分组成:

· bootfs :包含 bootloader (引导加载程序) 和 kernel (内核)

· rootfs:root 文件系统,包含的就是典型的 Linux 系统的 /dev ,/proc ,/bin ,/etc 等标准目录和文件。

1):DockerFile 镜像原理:↓ ↓ ↓

~ Docker 镜像是由特殊的文件系统叠加而成。

~ 最低端是bootfs,并使用宿主机的 bootfs

~ 第二层是 rootfs 文件系统 rootfs,称为base image

~ 然后再往上可以叠加其他的镜像文件

~ 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供一个统一的视角,

   这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。

~ 一个镜像可以放在另一个镜像上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。

 

 

Docker 镜像不能修改,修改了别人就不能用了 ...

~ 当从一个镜像启动容器时,Docker 会在最顶层加载一个读写文件系统作为容器。

最大作用就是 复用 。

2):DockerFile 镜像制作:↓ ↓ ↓

~ Docker 镜像如何制作?

1、容器转为镜像

docker commit 容器ID 镜像名称:版本号

 

镜像不能直接传输:可以将镜像文件压缩成文件进行传输。

docker save -o 压缩文件名称 镜像名称:版本号

 

 还原镜像

docker load -i 压缩文件名称

2、dockerfile 概念

~ Dockerfile  是一个文本文件

~ 包含了一条条指令

~ 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像

~ 对于开发人员:可以为开发团队提供一个完全一致的开发环境

~ 对于测试人员:可以直接拿着开发时所构建的镜像或者通过Dockerfile 文件

   构建一个新的镜像开始工作了。

~ 对于运维人员,在部署时,可以实现应用的无缝移植

Dochub网址:https://hub.docker.com

 举例:contos

复制代码
FROM scratch                 # centos 基于一个空镜像
ADD centos-7-x86_64-docker.tar.xz /   # 把centos 对应的压缩文件 添加到当前的根目录

LABEL \                                      # 声明一些标签信息(可忽略掉)
    org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20201113" \
    org.opencontainers.image.title="CentOS Base Image" \
    org.opencontainers.image.vendor="CentOS" \
    org.opencontainers.image.licenses="GPL-2.0-only" \
    org.opencontainers.image.created="2020-11-13 00:00:00+00:00"

CMD ["/bin/bash"]                      # 启动容器执行的指令
复制代码

3):DockerFile 案例:↓ ↓ ↓

~ 定义 dockerfile,发布springboot 项目

实现步骤:↓

1、定义父镜像:FROM java:8
2、定义作者信息:MAINTAINR itheima<ixxx#xx.cn>
3、将jar包添加到容器:ADD springboot.jar  app.jar
4、定义容器启动执行的命令:CMD java -jar app.jar
5、通过dockerfile构建镜像:docker bulid -f dockerfile 文件路径 -t镜像名称:版本

定义 dockerfile 文件:

FROM  java:8
MAINTAINER itheima <mlq@cc.cn>
ADD docker-0.0.1-SNAPSHOT.jar app.jar
CMD java -jar app.jar

 

 

DockerFile 案例自定义:↓ ↓ ↓

案例需求:

~ 自定义centos7镜像;

  · 默认登录路径为  /usr

  · 可以使用 vim

~ 实现步骤;

  · 定义父镜像:FROM centos:7

  · 定义作者信息:MAINTAINER itheima <itheima@itcast.cn>

  · 执行安装 win 命令:RUN yum install -y vim

  · 定义默认的工作目录:WORKDIR/usr

    · 定义容器启动执行的命令:CMD/bin/bash

dockerfile:↓

FROM centos:7
MAINTAINER itheima <cc@.cn>
RUN yum install -y vim
WORKDIR /usr
CMD /bin/bash

Docker 服务编排:↓ ↓ ↓

~ 服务编排概念:

  微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。

  要从Dockerfile build image 或者去 dockerhub 拉取 image

  要创建多个 container

  要管理这些 container (启动停止删除)

  服务编排:按照一定的业务规则批量管理容器

~ Docker Compose 概述:

  Docker Compose 是一个编排多容器分布式部署工具,提供命令集管理容器化应用的完整开发周期,包含服务构建,启动和停止。

  使用步骤:↓

  1、利用 Dockerfile 定义运行环境镜像

  2、使用 docker-compose.yml 定义组成应用的各服务

  3、运行 docker-compose up 启动应用

  

~ 安装 Compose:

复制代码
# Compose 目前已经完全支持 Linux 、 Mac OS 和 Windows,在我们安装Compose之前,需要先安装Docker。
# 下面我们以编译好的二进制包方式安装在Linux系统中。

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

# 设置文件可执行权限
chmod +x /usr/local/bin/docker-compose

# 查看版本信息
docker-compose -version

#卸载Docker Compose
# 二进制包方式安装的,删除二进制文件即可
rm /usr/local/bin/docker-compose

复制代码
复制代码
# 使用Docker Compose 编排 nginx+SpringBoot项目

1、创建 docker-compose 目录
   mkdir /opt/docker/docker-compose
   cd /opt/docker/docker-compose

2、编写 docker-compose.yml 文件
复制代码
复制代码
version:'3'
services:
nginx:
image: nginx
ports:
- 80:80
links:
- app
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
app:
image: app
expose:
- "8080"

复制代码
3、创建 ./nginx/conf.d 目录
mkdir -p ./nginx/conf.d
复制代码
4、在 ./nginx/conf.d 目录下 编写 itheima.conf 文件

server{
   listen 80;
   access_log off;
   
   location / {
      proxy_pass http://app:8080; 
   }
}
复制代码
5、在 /docker-compose 目录下 使用 docker-compose 启动容器
docker-compose up

6、测试访问
http://192.168.211.102/api/docker

Docker 私有仓库:↓ ↓ ↓

  docker 官方的 Docker hub (https://hub.docker.com) 是一个用于管理公共镜像的仓库,我们可以从上面拉取镜像到本地,也可以把我们自己的镜像推送上去。

但是,有时候我们的服务器无法访问互联网,或者你不希望将自己的镜像放到公网当中,那我们就需要搭建自己的私有仓库来储存和管理自己的镜像。

复制代码
# 私有仓库搭建

# 1、拉取私有仓库镜像
docker pull registry

# 2、启动私有仓库容器
docker run -id --name=registry -p 5000:5000 registry

# 3、打开浏览器 输入地址 http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]}表示私有仓库 搭建成功

# 4、修改 daemon.json
vim /etc/docker/daemon.json

# 在上述文件中添加一个key ,保存退出。此步用于让 docker 信任私有仓库地址;注意将私有仓库服务器ip修改为自己私有服务器真实地址ip
{"insecure-registries":["私有仓库服务器ip:5000"]}

# 5、重启 docker 服务
systemctl restart docker
docker start registry

复制代码
复制代码
# 将镜像上传至私有仓库

#1、标记镜像为私有仓库的镜像
docker tag centos:7 私有仓库服务器ip:5000/centos:7

#2、上传标记镜像
docker push 私有仓库服务器IP:5000/centos:7
复制代码
# 从私有仓库拉取镜像

docker pull 192.168.211.102/cc_centos:1

Docker 相关概念:↓ ↓ ↓

容器就是将软件打包成标准化单元,以用于开发,交付和部署。

  · 容器镜像是轻量级的、可执行的独立软件包,包含软件运行所需要的的所有内容:代码、运行时环境、系统工具、系统库和设置。

  · 容器化软件在任何环境中都能够始终如一地运行。

  · 容器赋予了软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间在相同基础设施上运行不同软件的冲突。

 

~ docker 容器虚拟化 与 传统虚拟机比较:

相同:

  容器和虚拟机具有相似的资源隔离和分配优势

不同:

  容器虚拟化的是操作系统,虚拟机虚拟化的是硬件。

  传统虚拟机可以运行不同的操作系统,容器只能运行同一类型操作系统。

 

 

 

 

Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear.

面对过去无怨无悔,把握现在充满信心,备战未来无所畏惧。保持信念,克服恐惧!一点一滴的积累,一点一滴的沉淀,学技术需要不断的积淀!

posted @   coding++  阅读(376)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示