docker官网:https://hub.docker.com/
docker中文菜鸟教程:https://www.runoob.com/docker/docker-tutorial.html
1. Docker架构与容器化
docker的底层原理
- Docker是基于Google公司推出的Golang语言开发而来,基于Linux内核的Cgroups、NameSpace,以及Union Fs等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。
- 对进程进行封装隔离,属于操作系统层面的虚拟化技术。
- 利用Docker可以实现开发,测试,生产环境的部署一致性,极大的减少运维成本。
docker安装部署
docker最核心的组件 - image镜像,构建容器(我们讲应用程序运行所需的环境,打包为镜像文件)。
- Container,容器(你的应用程序,就跑在容器中)
- 镜像仓库(dockerhub)(保存镜像文件,提供上传下载镜像)作用好比github
- Dockerfile,将你部署项目的操作,写成一个部署脚本,这就是dockerfile,且该脚本还能够构建出镜像文件
docker容器化技术
2. Linux环境安装docker
官网详细步骤:https://docs.docker.com/engine/install/centos/
# 移除旧版本docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 配置docker yum源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 最新 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 启动 docker (只是当前启动,关机重启后还是要重新启动)
sudo systemctl start docker
# 开机自启动docker; enable + start 二合一
systemctl enable docker --now
# 配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://dockerproxy.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com",
"https://3zdb8399.mirror.aliyuncs.com",
"https://docker.m.daocloud.io",
"https://docker.mirrors.sjtug.sjtu.edu.cn"
]
}
EOF
# 重新加载重启
sudo systemctl daemon-reload
sudo systemctl restart docker
3. docker常见命令
演示:使用docker启动一个nginx,发布自己的页面,让其他人能访问。
镜像操作
容器操作
-d
后台启动
-P
是容器内部端口随机映射到主机的端口。
-p
是容器内部端口绑定到指定的主机端口。
保存镜像
发布镜像
完整命令如下:
#查看运行中的容器
docker ps
#查看所有容器
docker ps -a
#搜索镜像
docker search nginx
#下载镜像
docker pull nginx
#下载指定版本镜像
docker pull nginx:1.26.0
#查看所有镜像
docker images
#删除指定id的镜像
docker rmi e784f4560448
#运行一个新容器(前台启动,会阻塞控制台)
docker run nginx
#停止容器 容器名或者id
docker stop keen_blackwell
#启动容器
docker start 592f
#重启容器
docker restart 592f
#查看容器资源占用情况
docker stats 592f
#查看容器日志
docker logs 592f
#删除指定容器(运行中容器删除回报错,需要先停止)
docker rm 592f
#强制删除指定容器
docker rm -f 592f
# 后台启动容器
docker run -d --name mynginx nginx
# 后台启动并暴露端口(端口映射:外部主机端口-->内部容器端口)
docker run -d --name mynginx -p 80:80 nginx
# 进入容器内部
docker exec -it mynginx /bin/bash
# 提交容器变化打成一个新的镜像
docker commit -m "update index.html" mynginx mynginx:v1.0
# 保存镜像为指定文件
docker save -o mynginx.tar mynginx:v1.0
# 删除多个镜像
docker rmi bde7d154a67f 94543a6c1aef e784f4560448
# 加载镜像
docker load -i mynginx.tar
# 登录 docker hub
docker login
# 重新给镜像打标签
docker tag mynginx:v1.0 codese/mynginx:v1.0
# 推送镜像
docker push codese/mynginx:v1.0
# 清理掉所有处于终止状态的容器。
docker container prune
4. docker 存储
使用外部目录挂载、数据卷,保证容器出现问题或删除后,容器的数据不丢失。
#查看所有容器情况
docker ps -a
#查看所有容器ID
docker ps -aq
#批量删除所有容器
docker rm -f $(docker ps -aq)
两种方式,注意区分:
● 目录挂载: -v /app/nghtml:/usr/share/nginx/html
● 卷映射:-v ngconf:/etc/nginx
目录挂载
注意细节:
使用目录挂载时,默认以挂载目录文件为准。而容器一启动就会根据启动参数自动创建需要挂载的目录,而且初始是空的,这意味着如果是访问页面或者读取配置文件就会报错。(除非提前放置相应的文件)
卷映射
查看卷的相关操作
# 查看所有的卷
docker volume ls
# 创建一个卷
docker volume create haha
# 查看卷详情
docker volume inspect ngconf
5. docker网络
只要docker就有一个默认的网络网卡docker0
,每启动一个容器都会加入到这个网络且分配iP。
#批量删除所有容器
docker rm -f $(docker ps -aq)
# 查看网卡信息
ip a
# 启动两个容器
docker run -d -p 88:80 --name app1 nginx
docker run -d -p 99:80 --name app2 nginx
# 查看容器详情
docker inspect app1
docker inspect app2
#进入容器内部访问
docker exec -it app1 /bin/bash
curl http://192.168.31.59:99 # 绕了一圈外面在进去,不可取
curl http://172.17.0.3:80 # 容器内部直接访问
优化—使用自定义网络
#批量删除所有容器
docker rm -f $(docker ps -aq)
# 自定义网络
docker network create mynet
# 查看
docker network ls
# 启动两个容器
docker run -d -p 88:80 --name app1 --network mynet nginx
docker run -d -p 99:80 --name app2 --network mynet nginx
# 查看容器详情
docker inspect app1
docker inspect app2
#进入容器内部访问
docker exec -it app1 /bin/bash
curl http://app2:80 # 内部访问,稳定域名
案例:redis主从同步集群
#自定义网络
docker network create mynet
#主节点
docker run -d -p 6379:6379 \
-v /app/rd1:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=master \
-e REDIS_PASSWORD=123456 \
--network mynet --name redis01 \
bitnami/redis
#从节点
docker run -d -p 6380:6379 \
-v /app/rd2:/bitnami/redis/data \
-e REDIS_REPLICATION_MODE=slave \
-e REDIS_MASTER_HOST=redis01 \
-e REDIS_MASTER_PORT_NUMBER=6379 \
-e REDIS_MASTER_PASSWORD=123456 \
-e REDIS_PASSWORD=123456 \
--network mynet --name redis02 \
bitnami/redis
使用redis数据库连接工具测试
在主数据库添加、修改、删除数据,看从数据库的变化。
容器启动MySQL
docker run -d -p 3306:3306 \
-v /app/myconf:/etc/mysql/conf.d \
-v /app/mydata:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0.37-debian
6. Docker Compose (批量管理容器工具)
案例:
compose编写文档:https://docs.docker.com/reference/compose-file/
#批量删除原来容器
docker rm -f $(docker ps -aq)
#创建网络
docker network create blog
#启动mysql
docker run -d -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-v mysql-data:/var/lib/mysql \
-v /app/myconf:/etc/mysql/conf.d \
--restart always --name mysql \
--network blog \
mysql:8.0
#启动wordpress
docker run -d -p 8080:80 \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=123456 \
-e WORDPRESS_DB_NAME=wordpress \
-v wordpress:/var/www/html \
--restart always --name wordpress-app \
--network blog \
wordpress:latest
换成compose写法批量管理:
#批量删除原来容器
docker rm -f $(docker ps -aq)
#批量删除原来的卷
docker volume rm mysql-data wordpress
#删除原来的网络
docker network rm blog
# 编辑配置文件
vim compose.yaml
# 启动
docker compose -f compose.yaml up -d
# 下线(卷和目录不会被移除)
docker compose -f compose.yaml down
# 下线(删除镜像和目录)
docker compose -f compose.yaml down --rmi all -v
compose.yaml配置文件如下:
name: myblog
services:
#第一个应用
mysql:
container_name: mysql #自定义容器名
image: mysql:8.0 # 使用镜像及版本
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always #开机自启动
networks:
- blog
#第二个应用
wordpress:
image: wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
restart: always #开机自启动
networks:
- blog
depends_on: #代表这个应用启动依赖mysql
- mysql
#声明用到的卷
volumes:
mysql-data:
wordpress:
# 声明网络
networks:
blog:
特性
● 增量更新
○ 修改 Docker Compose 文件。重新启动应用。只会触发修改项的重新启动。
● 数据不删
○ 默认就算down了容器,所有挂载的卷不会被移除。比较安全
7. Dockerfile 制作镜像
构建镜像
Dockerfile 是一个文本文件,包含了构建 Docker 镜像的所有指令。
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
通过定义一系列命令和参数,Dockerfile 指导 Docker 构建一个自定义的镜像。
我们使用命令 docker build , 从零开始来创建一个新的镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
官方文档:https://docs.docker.com/reference/dockerfile/
vim Dockerfile:
FROM openjdk:17
LABEL author=codeSE
COPY app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
制作容器镜像并启动
# 构建
docker build -f Dockerfile -t myjavaapp:v1.0 .
# 查看镜像
dockers images
# 启动
docker run -d -p 8888:8080 myjavaapp:v1.0
制作其他语言镜像参考官方:https://docs.docker.com/language/
8. 镜像分层存储
使用docker ps -s
看一下区别
使用docker image history nginx和docker image histor mynginx:v1.0
看一下区别
再使用docker inspect ngin和docker inspect mynginx:v1.0
查看两个镜像区别,说明相同的部分就采用了共同的分层存储,不同的才分一层存储。
9. docker 常见的中间件安装
#批量删除原来容器
docker rm -f $(docker ps -aq)
#批量删除原来的卷
docker volume rm $(docker volume ls -q)
#删除原来的网络
docker network rm blog
# 关闭内存分页
sudo swapoff -a
# Edit the sysctl config file
sudo vi /etc/sysctl.conf
# Add a line to define the desired value
# or change the value if the key exists,
# and then save your changes.
vm.max_map_count=262144
# Reload the kernel parameters using sysctl
sudo sysctl -p
# Verify that the change was applied by checking the value
cat /proc/sys/vm/max_map_count
yaml
注意:
● 将下面文件中 kafka 的 192.168.31.59 改为你自己的服务器IP。
● 所有容器都做了时间同步,这样容器的时间和linux主机的时间就一致了
准备一个 compose.yaml文件,内容如下:
name: devsoft
services:
redis:
image: bitnami/redis:latest
restart: always
container_name: redis
environment:
- REDIS_PASSWORD=123456
ports:
- '6379:6379'
volumes:
- redis-data:/bitnami/redis/data
- redis-conf:/opt/bitnami/redis/mounted-etc
- /etc/localtime:/etc/localtime:ro
mysql:
image: mysql:8.0.31
restart: always
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=123456
ports:
- '3306:3306'
- '33060:33060'
volumes:
- mysql-conf:/etc/mysql/conf.d
- mysql-data:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
rabbit:
image: rabbitmq:3-management
restart: always
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
- RABBITMQ_DEFAULT_USER=rabbit
- RABBITMQ_DEFAULT_PASS=rabbit
- RABBITMQ_DEFAULT_VHOST=dev
volumes:
- rabbit-data:/var/lib/rabbitmq
- rabbit-app:/etc/rabbitmq
- /etc/localtime:/etc/localtime:ro
opensearch-node1:
image: opensearchproject/opensearch:2.13.0
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster # Name the cluster
- node.name=opensearch-node1 # Name the node that will run in this container
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligibile to serve as cluster manager
- bootstrap.memory_lock=true # Disable JVM heap memory swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
- "DISABLE_INSTALL_DEMO_CONFIG=true" # Prevents execution of bundled demo script which installs demo certificates and security configurations to OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # Disables Security plugin
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data # Creates volume called opensearch-data1 and mounts it to the container
- /etc/localtime:/etc/localtime:ro
ports:
- 9200:9200 # REST API
- 9600:9600 # Performance Analyzer
opensearch-node2:
image: opensearchproject/opensearch:2.13.0
container_name: opensearch-node2
environment:
- cluster.name=opensearch-cluster # Name the cluster
- node.name=opensearch-node2 # Name the node that will run in this container
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligibile to serve as cluster manager
- bootstrap.memory_lock=true # Disable JVM heap memory swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
- "DISABLE_INSTALL_DEMO_CONFIG=true" # Prevents execution of bundled demo script which installs demo certificates and security configurations to OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # Disables Security plugin
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- /etc/localtime:/etc/localtime:ro
- opensearch-data2:/usr/share/opensearch/data # Creates volume called opensearch-data2 and mounts it to the container
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.13.0
container_name: opensearch-dashboards
ports:
- 5601:5601 # Map host port 5601 to container port 5601
expose:
- "5601" # Expose port 5601 for web access to OpenSearch Dashboards
environment:
- 'OPENSEARCH_HOSTS=["http://opensearch-node1:9200","http://opensearch-node2:9200"]'
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # disables security dashboards plugin in OpenSearch Dashboards
volumes:
- /etc/localtime:/etc/localtime:ro
zookeeper:
image: bitnami/zookeeper:3.9
container_name: zookeeper
restart: always
ports:
- "2181:2181"
volumes:
- "zookeeper_data:/bitnami"
- /etc/localtime:/etc/localtime:ro
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: 'bitnami/kafka:3.4'
container_name: kafka
restart: always
hostname: kafka
ports:
- '9092:9092'
- '9094:9094'
environment:
- KAFKA_CFG_NODE_ID=0
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://0.0.0.0:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://192.168.31.59:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- ALLOW_PLAINTEXT_LISTENER=yes
- "KAFKA_HEAP_OPTS=-Xmx512m -Xms512m"
volumes:
- kafka-conf:/bitnami/kafka/config
- kafka-data:/bitnami/kafka/data
- /etc/localtime:/etc/localtime:ro
kafka-ui:
container_name: kafka-ui
image: provectuslabs/kafka-ui:latest
restart: always
ports:
- 8080:8080
environment:
DYNAMIC_CONFIG_ENABLED: true
KAFKA_CLUSTERS_0_NAME: kafka-dev
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092
volumes:
- kafkaui-app:/etc/kafkaui
- /etc/localtime:/etc/localtime:ro
nacos:
image: nacos/nacos-server:v2.3.1
container_name: nacos
ports:
- 8848:8848
- 9848:9848
environment:
- PREFER_HOST_MODE=hostname
- MODE=standalone
- JVM_XMX=512m
- JVM_XMS=512m
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=nacos-mysql
- MYSQL_SERVICE_DB_NAME=nacos_devtest
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos
- MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
- NACOS_AUTH_IDENTITY_KEY=2222
- NACOS_AUTH_IDENTITY_VALUE=2xxx
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
- NACOS_AUTH_ENABLE=true
volumes:
- /app/nacos/standalone-logs/:/home/nacos/logs
- /etc/localtime:/etc/localtime:ro
depends_on:
nacos-mysql:
condition: service_healthy
nacos-mysql:
container_name: nacos-mysql
build:
context: .
dockerfile_inline: |
FROM mysql:8.0.31
ADD https://raw.githubusercontent.com/alibaba/nacos/2.3.2/distribution/conf/mysql-schema.sql /docker-entrypoint-initdb.d/nacos-mysql.sql
RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/nacos-mysql.sql
EXPOSE 3306
CMD ["mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
image: nacos/mysql:8.0.30
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=nacos_devtest
- MYSQL_USER=nacos
- MYSQL_PASSWORD=nacos
- LANG=C.UTF-8
volumes:
- nacos-mysqldata:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
ports:
- "13306:3306"
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
interval: 5s
timeout: 10s
retries: 10
prometheus:
image: prom/prometheus:v2.52.0
container_name: prometheus
restart: always
ports:
- 9090:9090
volumes:
- prometheus-data:/prometheus
- prometheus-conf:/etc/prometheus
- /etc/localtime:/etc/localtime:ro
grafana:
image: grafana/grafana:10.4.2
container_name: grafana
restart: always
ports:
- 3000:3000
volumes:
- grafana-data:/var/lib/grafana
- /etc/localtime:/etc/localtime:ro
volumes:
redis-data:
redis-conf:
mysql-conf:
mysql-data:
rabbit-data:
rabbit-app:
opensearch-data1:
opensearch-data2:
nacos-mysqldata:
zookeeper_data:
kafka-conf:
kafka-data:
kafkaui-app:
prometheus-data:
prometheus-conf:
grafana-data:
启动
# 在 compose.yaml 文件所在的目录下执行
docker compose up -d
# 等待启动所有容器
注意注意:
使用https://raw.githubusercontent.com/alibaba/nacos/2.3.2/distribution/conf/mysql-schema.sql这个地址会出现访问不了的情况,建议更换地址。或者直接去git仓库找到对应的nacos版本找到distribution/conf/mysql-schema.sql 直接下载在本地。通过本地的文件目录执行它。
访问测试
● zookeeper可视化工具下载:
○ https://github.com/vran-dev/PrettyZoo/releases/download/v2.1.1/prettyZoo-win.zip
● redis可视化工具下载:
○https://github.com/qishibo/AnotherRedisDesktopManager/releases/download/v1.6.4/Another-Redis-Desktop-Manager.1.6.4.exe
组件(容器名) | 介绍 | 访问地址 | 账号/密码 | 特性 |
---|---|---|---|---|
Redis(redis) | k-v 库 | 你的ip:6379 | 单密码模式:123456 | 已开启AOF |
MySQL(mysql) | 数据库 | 你的ip:3306 | root/123456 | 默认utf8mb4字符集 |
Rabbit(rabbit) | 消息队列 | 你的ip:15672 | rabbit/rabbit | 暴露5672和15672端口 |
OpenSearch(opensearch-node1/2) | 检索引擎 | 你的ip:9200 | 内存512mb;两个节点 | |
opensearch-dashboards | search可视化 | 你的ip:5601 | ||
Zookeeper(zookeeper) | 分布式协调 | 你的ip:2181 | 允许匿名登录 | |
kafka(kafka) | 消息队列 | 你的ip:9092外部访问:9094 | 占用内存512mb | |
kafka-ui(kafka-ui) | kafka可视化 | 你的ip:8080 | ||
nacos(nacos) | 注册/配置中心 | 你的ip:8848 | nacos/nacos | 持久化数据到MySQL |
nacos-mysql(nacos-mysql) | nacos配套数据库 | 你的ip:13306 | root/root | |
prometheus(prometheus) | 时序数据库 | 你的ip:9090 | ||
grafana(grafana) | 你的ip:3000 | admin/admin |
Docker 小结
- Docker Daemon
安装使用Docker,得先运行DockerDaemon进程,用于管理docker,如:
- 镜像 imagese
- 容器 containerse
- 网络 network。
- 数据卷 Data Volumes
-
Rest接口
提供和Daemon交互的API接口 -
Docker Client
客户端使用REST API和Docker Daemon进行访问. -
Docker平台组成
-
lmages
镜像是一个只读模板,用于创建容器,也可以通过Dockerfile文本描述镜像的内。
容镜像的概念类似于编程开发里面向对象的类,从一个基类开始(基础镜像Base lmage)构建容器的过程,就是运行镜像,生成容器实例。
Docker镜像的描述文件是Dockerfile,包含了如下的指令:
。FROM 定义基础镜像
。MAINTAINER作者
。RUN 运行Linux命令
。ADD 添加文件/目录
。ENV 环境变量
。CMD 运行进程
- Container
容器是一个镜像的运行实例,镜像 >容器。
创建容器的过程:
- 获取镜像,如
docker pull centos
,从镜像仓库拉取 - 使用镜像创建容器
- 分配文件系统,挂载一个读写层,在读写层加载镜像
- 分配网络/网桥接口,创建一个网络接口,让容器和宿主机通信
- 容器获取IP地址
- 执行容器命令,如/bin/bash
- 反馈容器启动结果。.
- Registry
Docker镜像需要进行管理,docker提供了Recistr仓库,其实它也是一个容器。可以用于可以基干该容器运行私有仓库。
也可以使用Docker Hub互联网公有镜像仓库, - 安装Docker
提前准备好一个宿主机(vmware去创建一个linux机器,然后安装docker去使用)
- 安装环境初始化