Docker学习(一)
容器化部署Docker
Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?
- Docker允许开发汇总将应用、依赖、函数库、配置一起打包,形成可以直接安装的镜像
- Docker应用运行在容器中,使用沙箱机制,相互隔离
Docker如何解决开发、测试、生产环境有差异的问题?
Docker镜像中包含完整的运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
Docker与虚拟机的区别:
虚拟机是使用Hypervisor技术在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在Windows系统里面运行Ubuntu系统。
特性 Docker 虚拟机 性能 接近原生 性能较差 硬盘占用 一般为MB 一般为GB 启动 秒级 分钟级
1. 概念
1.1 镜像(Image)
- Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像
1.2 容器(Container)
- 镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见
1.3 DockerHub
- DockerHub是一个Docker镜像的托管平台,这样的平台称为Docker Registry
- 国内也有类似于DockerHub的公开服务,比如网易云镜像服务、阿里云镜像库等
1.4 Docker
-
Docker是一个CS架构的程序,由两部分组成
- 服务端:Docker守护进程,负责处理Docker指令,管理镜像、容器等
- 客户端:通过命令或RestAPI向Docker服务端发送指令,可以在本地或远程向服务端发送指令
2. 安装Docker
2.1 CentOS7安装Docker
CentOS7系统下载地址:
http://mirrors.163.com/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-DVD-2009.iso
迅雷下载镜像文件有奇效,IDM平时下载很快,下载镜像开8线程只能跑到1M/s,迅雷直接10M/s
-
若之前安装过其他版本Docker,通过以下方式完成卸载:
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-lastest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine \ docker-ce
-
安装Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
-
更新yum本地镜像源
# 删除原有配置源目录 cd /etc rm -rf yum.repos.d # 新建配置源目录 mkdir yum.repos.d # 下载阿里镜像源 cd yum.repos.d wget https://mirrors.aliyun.com/repo/Centos-7.repo # 更新yum缓存 yum makecache
-
更新软件源信息
参考:https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.40491b11PUGxwo
# step 1: 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3 # Step 4: 更新并安装Docker-CE yum makecache fast yum -y install docker-ce # Step 4: 开启Docker服务 service docker start
-
关闭防火墙(为了学习Docker,开发中应该开启指定端口)
# 关闭防火墙应用 systemctl stop firewalld # 禁止开机启动防火墙 systemctl disable firewalld # 查看防火墙状态 systemctl status firewalld
-
配置Docker镜像源
mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://xm9ypajm.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker
-
2.2 Docker基本操作
镜像的命名规范:
- 镜像名称一般由两部分组成:
[respository]:[tag]
- respository:镜像名称
- tag:版本
- 如果没有指定tag时,默认是latest,代表最新版本的镜像
-
镜像相关指令
docker images
:查看当前所有镜像docker pull [respository]:[tag]
:从镜像仓库中拉取指定镜像docker save -o [Path/FileName.tar] [respository]:[tag]
:将指定镜像打包docker load -i [Path/FileName.tar]
:将打包好的镜像加载到Docker中docker rmi [respository]:[tag]
:移除指定镜像
示例:
从DockerHub中拉取一个nginx镜像并查看
docker pull nginx
docker images
将nginx镜像打包到本地
docker save -o ~/nginx.tar nginx:latest
将镜像文件从本地tar包加载
docker load -i ~/nginx.tar
docker images
-
容器相关命令
docker run
:创建并运行一个容器docker pause
:暂停运行docker unpause
:继续运行docker stop
:停止运行docker start
:运行docker ps
:查看所有运行容器及状态docker logs
:查看容器运行日志docker exec
:进入容器执行命令docker rm
:删除指定容器
示例:
运行一个nginx容器
docker run --name mn -p 80:80 -d nginx
--name
:指定容器名称-p
:指定端口映射-d
:后台运行
docker ps
查看指定容器运行日志
docker logs mn
跟踪查看运行日志:
docker logs -f mn
进入容器执行命令
docker exec -it mv bash
exit
:退出容器停止运行容器
docker stop mn
查看所有容器包括未运行的
docker ps -a
运行容器
docker start mn
删除容器
docker rm
:只能删除未运行的容器
docker rm -f mn
:强制删除容器,无论是否运行
示例:运行一个持久化存储的redis容器,并通过redis-cli设置num=666
运行容器
docker run --name my-redis -p 6379:6379 -d redis redis-server --appendonly yes
进入容器
docker exec -it my-redis bash
启动redis-cli
redis-cli
设置num=666
set num 666
退出redis-cli,退出容器
exit
docker exec -it my-redis redis-cli
:直接进入容器中启动redis-cli
2.3 数据卷操作
数据卷的作用:将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
-
基本语法:
docker volume [COMMAND]
- COMMAND
- create:创建一个volume
- inspect:显示一个或多个volume的信息
- ls:列出所有的volume
- prune:删除未使用的volume
- rm:删除一个或多个指定的volume
- COMMAND
-
挂载数据卷
-
创建并运行容器时指定数据卷的挂载目录,若数据卷不存在,则自动创建数据卷
docker run \ --name mn \ -p 80:80 \ -v html:/usr/share/nginx/html \ -d nginx
-
-
挂载目录
-
docker run \ --name some-mysql \ -e MYSQL_ROOT_PASSWORD=root \ -p 3306:3306 \ -v /tmp/mysql/data:/var/lib/mysql \ -v /tmp/mysql/conf/hmy.cnf:/etc/mysql/conf.d/hmy.cnf \ -d mysql:latest
数据卷挂载与目录挂载
- 数据卷挂载耦合度低,有docker来管理目录,但是目录较深,不好找
- 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
-
3. 镜像结构
镜像就是将应用程序及其所需要的系统函数库、环境、配置、依赖打包而成的
- 基础镜像(BaseImage):应用依赖的系统函数库、环境变量、配置、文件系统等
- 入口(Entrypoint):镜像运行入口,一般是程序启动的脚本和参数
- 层(Layer):在BaseImage基础上添加安装包、依赖、配置等,每次操作形成新的一层
镜像是分层结构,每一层称一个Layer
3.1 自定义镜像
Dockerfile:一个文本文件,指令的合集,用指令来说明要执行什么操作来构建镜像,每一个指令都会形成一层Layer
指令 说明 示例 FROM 指定BaseImage FROM centos:6 ENV 设置环境变量,可在后面指令使用 ENV key value COPY 拷贝本地文件到镜像的指定目录 COPY ./mysql-5.7.rpm /tmp RUN 执行Linux的shell命令,一般是安装过程的命令 RUN yum install gcc EXPOSE 指定容器运行时监听的端口,是给镜像使用者看的 EXPOSE 8080 ENTRYPOINT 镜像中应用的启动命令,容器运行时调用 ENTRYPOINT java -jar xx.jar
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
-
mkdir -p /tmp/docker-demo
-
将
docker-demo.jar
jdk8.tar.gz
Dockerfile
上传至/tmp/docker-demo
-
docker build -t javaweb:1.0 .
-
docker images
-
docker run --name web -p 8090:8090 -d javaweb:1.0
-
访问
ip:8090/hello/count
我们发现在Dockerfile中构建jdk环境的操作是可复用的,我们应该把构建jdk环境的部分构建一个镜像,这样以后就可以直接使用了,而java:8-alpine帮我们做了这件事
3.2 DockerCompose
DockerCompose可以基于Compose文件帮我们快速部署分布式应用,而无需手动一个个创建和运行容器
Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行
version: "3.9" services: mysql: #指定服务名称 image: mysql:8.0.21 # 指定镜像文件 environment: #设置环境变量 MYSQL_ROOT_PASSWORD: 123456 volumes: #数据卷挂载 - /tmp/mysql/data:/var/lib/mysql - /tmp/mysql/conf/hym.cnf:/etc/mysql/conf.d/hym.cnf web: #指定服务名称 build: . #从当前目录中构建镜像 ports: #设置端口号 - "8090:8090"
书写格式参考规范:
- https://docs.docker.com/compose/compose-file/compose-file-v3/
- https://docs.docker.com/compose/compose-file/compose-file-v2/
3.2.1 安装DockerCompose
参考:https://docs.docker.com/compose/install/compose-plugin/#installing-compose-on-linux-systems
curl -SL https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
-
docker-compose
所在目录/usr/local/bin/docker-compose
-
给
docker-compose
添加可执行权限chmod +x docker-compose
-
Base自动补全命令
curl \ -L https://raw.githubusercontent.com/docker/compose/v2.6.1/contrib/completion/bash/docker-compose \ -o /etc/bash_completion.d/docker-compose
如果无法访问该地址,则修改本机hosts文件
echo "185.199.108.133 raw.githubusercontent.com" >> /etc/hosts
3.2.2 部署微服务集群
docker run \
--name my-mysql8 \
-e MYSQL_ROOT_PASSWORD=root \
-p 3306:3306 \
-d mysql:latest \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
FROM java:8-alpine COPY ./app.jar /tmp/app.jar ENTRYPOINT java -jar /tmp/app.jar
# docker-comspose配置文件语法版本 version: 3.8 services: nacos: images: nacos/nacos-server environment: MODE: standalone ports: - "8848:8848" mysql: images: mysql:8.0.31 environment: MYSQL_ROOT_PASSWORD: 996748 volumes: - "$PWD/mysql/data:/var/lib/mysql" - "$PWD/mysql/conf:/etc/mysql/conf.d" user-service: build: ./user-service order-service: build: ./order-service gateway: build: ./gateway ports: - "10010:10010"
4. Docker镜像仓库
4.1 配置Docker信任地址
我们的私服采用的是http协议,默认不被Docker信任
# 编辑Docker服务守护进程配置文件
vi /etc/docker/daemon.json
# 添加内容
"insecure-registries":["http://192.168.96.130:8080"]
# 重新加载Docker服务守护进程
systemctl daemon-reload
# 重启Docker
systemctl restart docker
4.2 使用Docker部署带有图形界面的DockerRegistry
version: '3.0'
services:
registry:
image: registry
volumes:
- ./registry-data:/var/lib/registry
ui:
image: joxit/docker-registry-ui:1.5-static
ports:
- 8080:80
environment:
- REGISTRY_TITLE=絷缘私有仓库
- REGISTRY_URL=http://registry:5000
depends_on:
- registry
mkdir /tmp/docker-registry-ui
cd /tmp/docker-registry-ui
touch docker-compose.yml
vim docker-compose.yml
docker-compose up -d
4.3 在私有镜像仓库推送/拉取镜像
# 将现有镜像打包成为私有镜像
docker tag nginx:latest 192.168.96.130:8080/nginx:latest
# 将私有镜像推送到私有仓库
docker push 192.168.96.130:8080/nginx:latest
# 将私有镜像拉取到当前环境
docker pull 192.168.96.130:8080/nginx:latest
原文作者:絷缘
作者邮箱:zhiyuanworkemail@163.com
原文地址:https://zhiyuandnc.github.io/doBPQq_Z4/
版权声明:本文为博主原创文章,转载请注明原文链接作者信息