Docker学习笔记

Docker是基于Linux的容器虚拟化技术 Docker的目标是“Build, Ship and Run Any App, Anywhere”构建,发布和运行任何应用程序,在任何地方,是云原生架构中的关键技术之一

Docker

初识Docker

Docker是基于Go语言实现的云开源项目。

Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”。

Linux容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用打成镜像,通过镜像成为运行在Docker容器上面的实例,而 Docker容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作。

解决了运行环境和配置问题的软件容器, 方便做持续集成并有助于整体发布的容器虚拟化技术。

Docker的基本组成

  • 镜像(image):我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件
  • 容器(container):容器是用镜像创建的运行实例。容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台
  • 仓库(repository):是集中存放镜像文件的场所。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云等

前面笔记丢了糊弄一下

前面笔记丢了糊弄一下

前面笔记丢了糊弄一下

正文开始 ↓

Docker 安装

https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b11MyHd3k

# 一键安装
bash <(curl -sSL https://linuxmirrors.cn/docker.sh)
# 官方
wget http://get.docker.com -o docker_install.sh

Docker 常用命令

pull

docker pull redis
从远程拉取镜像到本地

run

docker run hello-world
docker run -it -name ubuntu-container ubuntu:latest /bin/bash
通过镜像启动一个容器,镜像查找顺序 本地 -> 远程仓库

参数

  • --name 指定容器名称
  • -d 后台运行并返回容器的ID
  • -i 以交互模式运行容器通常和 -t 一起使用
  • -t 为容器分配一个伪输入终端 也即启动交互式容器
  • -p 主机端口:容器端口 端口映射
  • -P 随机端口映射

exec

docker exec -it [id | container name] [command]
在容器中执行额外的命令 命令结束不会退出容器,相当于启动了一个新的线程

attach

docker attach ubuntu
进入到正在运行的容器终端中,如果在容器中使用命令结束运行,那么容器也会一并退出

logs

-f 流的形式,滚动查看日志

查看容器内产生的日志记录

system df

用来查看当前Docker的容器镜像等等占用系统资源的情况类似于Linux中的df -h

images

查看镜像列表

相关命令

  • rmi 删除镜像

ps

查看容器的状态列表 默认只显示正在运行的容器

参数

  • -q 只返回ID
  • -a 查看所有容器列表

cp

docker cp container-id:container-path host-path

从容器中拷贝文件到宿主机

export

docker export container-id > file-name

[ save ]

打包容器状态到镜像归档文件

import

docker import file author/image-name:tag

[ load ]

将打包的镜像文件导入到本地镜像列表

知识点

虚悬镜像 : 没有名字没有标签,只有ID和大小,镜像一般由构建出问题而产生,一般遇到都选择删除虚悬镜像

Docker 分层文件系统

docker 之所以轻量的原因是因为docker使用了union fs (联合文件系统)最大的特点就是文件存储是分层的

一个容器大致包括 bootfs > rootfs > software...

而bootfs是公用的,镜像文件中也就不需要包含,大大减小了镜像大小

分层文件系统还实现了让每一层都可以复用,这样同样的层只需要下载一次,一次下载多次复用,更节省本地的空间占用更加轻量。

镜像是只读的,容器才是可读写的,当容器导出为镜像时,容器上的所有操作又将转化为一层只读"操作记录"添加到原有的镜像中。以此类推,层层包裹。

<img src="https://www.reboots.top/api/file/dbe7a52130454012a7a6ef21d584f0d3.png" alt="image-20230806110515044" style="zoom: 50%;" />

阿里云远程仓库

1. 登录阿里云Docker Registry

$ docker login --username=wds824 registry.cn-hangzhou.aliyuncs.com

2. 从Registry中拉取镜像

$ docker pull registry.cn-hangzhou.aliyuncs.com/wds824/myubuntu:[镜像版本号]

3. 将镜像推送到Registry

$ docker login --username=wds824 registry.cn-hangzhou.aliyuncs.com$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/wds824/myubuntu:[镜像版本号]$ docker push registry.cn-hangzhou.aliyuncs.com/wds824/myubuntu:[镜像版本号]

Docker 私服

  • 安装私服
 docker run -d -p 5000:5000 -v /temp/myregistry/:/tmp/registry --privileged=true registry 
  • 使用私服

在使用前先配置docker信任该私服(如果有https则不需要)

修改 /etc/docker/deamon.conf

{
  "registry-mirrors": ["https://7n97q08r.mirror.aliyuncs.com"],
   //信任的服务器
  "insecure-registries":["192.168.6.101:5000"] 
}

Docker数据卷 volume

-v /root/app:/usr/local/app:rw --privilege=true

-v 主机路径:挂载路径:读写权限(默认是rw读写 可选ro --read only 只读) 使用特权(主机文件系统可能会出于安全策略禁止容器操作,使用该参数即可)

将主机上的目录挂载道容器内部,实现文件的共享

挂载的目录是脱离容器内的联合文件系统的,所以不会被打包到i镜像中,且一个目录可以同时挂载到多个容器当中。

  • 卷的继承

--volumes-from 其他容器

继承(复制)其他容器的挂载路径

Command Note

MySQL数据库:

注意修改 数据卷容器名 防止重复创建时冲突

8版本: 默认Utf8mb4字符集 Linux 上默认情况下,表名是区分大小写的;

5.7版本: 默认拉丁 字符集 Lantin1,需要手动修改。

⚠️ 开放公网访问一定要避免弱口令,避免默认端口,防止暴力破解。

# 8  
docker run --name mysql8 \
--privileged=true \
--restart always \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
-v mysql-log:/var/log/mysql \
-v mysql-data:/var/lib/mysql \
-v myql-conf:/etc/mysql/conf.d \
-d mysql:8 \
--lower_case_table_names=1 

# 5.7
docker run --name mysql57 \
  --privileged=true \
  --restart always \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e TZ=Asia/Shanghai \
  -v /etc/localtime:/etc/localtime:ro \
  -v /storage/docker/data/mysql/log:/var/log/mysql \
  -v /storage/docker/data/mysql/data:/var/lib/mysql \
  -v /storage/docker/data/mysql/conf:/etc/mysql/conf.d \
  -d mysql:5.7 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci

通过cnf配置文件修改字符集

  • my.cnf 示例
[client]
default_character_set=utf8mb4

[mysqld]
collation_server=utf8mb4_general_ci
character_set_server=utf8mb4
  • 查看编码
show variables like 'character%'

编码对比

编码 能存啥? 表情符号 (Emoji) 是否推荐
latin1 仅西欧文字 (英文、法文等) ❌ 不支持 ⚠️ 几乎不用
utf8 大部分文字,但不全 部分支持 (旧的) ❌ 不推荐
utf8mb4 所有文字 (全球语言) ✅ 完全支持 👍 强烈推荐

Redis缓存:

⚠️ Redis开放公网访问,要加密码,否则服务器将被攻击者利用。

# 有配置文件
docker run \
--name redis \
-v redis-conf:/usr/local/etc/redis \
-v redis-data:/data \
--privileged=true \
--restart always  \
-p 6379:6379  \
-itd redis \
redis-server /usr/local/etc/redis/redis.conf

# 无配置文件
docker run \
--name redis \
-v redis-data:/data \
--privileged=true \
--restart always  \
-p 6379:6379  \
-itd redis \

# 测试
docker exec -it redis redis-cli 

RabbitMQ

docker run \
 -e RABBITMQ_DEFAULT_USER=account \
 -e RABBITMQ_DEFAULT_PASS=password \
 --name mq \
 --hostname mq1 \
 -p 15672:15672 \
 -p 5672:5672 \
 -d rabbitmq:3.13.0-management

ElasticSearch

docker network create  es-net

docker run -d --name es --net es-net --privileged -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v es-data:/usr/share/elasticsearch/data -v es-config:/usr/share/elasticsearch/config -v es-plugins:/usr/share/elasticsearch/plugins elasticsearch:7.12.1 
# conf中的jvm配置,可以抑制内存占用
docker run -d --name kibana -v kibana-conf:/usr/share/kibana/config --net es-net -p 5601:5601 kibana:7.12.1
# 在配置文件中修改es的地址

# 安装ik 分词插件
elasticsearch-plugin install https://github.com/infinilabs/analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip
# 重启容器
docker restart es

MC-Server

我的世界 服务器

docker volume create mc
docker run 
    -itd \
    -e EULA=TRUE \
    -e VERSION=1.20.4 \
    -e ONLINE_MODE=false \
    -e ALLOW_CHEATS=true \
    -v mc:/data \
    -p 19132:19132/udp \
    -p 25565:25565 \
    --name mc itzg/minecraft-server

RustDesk

远程桌面中继节点

启动时可见key

# docker-compose.yml

networks:
  rustdesk-net:
    external: false

services:
  hbbs:
    container_name: hbbs
    ports:
      - 21115:21115
      - 21116:21116 # 自定义 hbbs 映射端口
      - 21116:21116/udp # 自定义 hbbs 映射端口
    image: rustdesk/rustdesk-server
    command: hbbs 
    volumes:
      - /root/rustDesk/nbbs:/root # 自定义挂载目录
    networks:
      - rustdesk-net
    depends_on:
      - hbbr
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 64M 

  hbbr:
    container_name: hbbr
    ports:
      - 21117:21117 # 自定义 hbbr 映射端口
    image: rustdesk/rustdesk-server
    command: hbbr
    volumes:
      - /root/rustDesk/hbbr:/root # 自定义挂载目录
    networks:
      - rustdesk-net
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 64M 

Minio

文件存储服务器

docker stop minio && docker rm minio

docker run \
    -itd \
    --restart always \
    --name minio \
    -p 9000:9000 \
    -p 9001:9001 \
    -v /root/minio/data:/data \
    -e "MINIO_ROOT_USER=account" \
    -e "MINIO_ROOT_PASSWORD=password" \
    minio/minio \
    server /data --console-address ":9001"