docker——容器化部署

2025-05-22 00:01:10

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)(保存镜像文件,提供上传下载镜像)作用好比githubDockerfile,将你部署项目的操作,写成一个部署脚本,这就是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

注意:需要打开防火墙指定端口外部才能访问,linux命令如下:

#firewall 防火墙指令

打开端口: firewall-cmd --permanent --add-port=端口号/协议

关闭端口: firewall-cmd --permanent --remove-port=端口号/协议

重新载入,才能生效 : firewall-cmd --reload

查询端口是否开放: firewall-cmd --query-port=端口/协议

查询所有开放的端口:firewall-cmd --zone=public --list-ports

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已开启AOFMySQL(mysql)数据库你的ip:3306root/123456默认utf8mb4字符集Rabbit(rabbit)消息队列你的ip:15672rabbit/rabbit暴露5672和15672端口OpenSearch(opensearch-node1/2)检索引擎你的ip:9200内存512mb;两个节点opensearch-dashboardssearch可视化你的ip:5601Zookeeper(zookeeper)分布式协调你的ip:2181允许匿名登录kafka(kafka)消息队列你的ip:9092外部访问:9094占用内存512mbkafka-ui(kafka-ui)kafka可视化你的ip:8080nacos(nacos)注册/配置中心你的ip:8848nacos/nacos持久化数据到MySQLnacos-mysql(nacos-mysql)nacos配套数据库你的ip:13306root/rootprometheus(prometheus)时序数据库你的ip:9090grafana(grafana)你的ip:3000admin/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去使用) 安装环境初始化

谁说世杯场上没中国人?10球童亮相俄罗斯
绿色联盟