文章目录
- Docker简介
- Docker和容器化技术简介
- Docker的核心组件
- 大白话理解Docker
- 安装Docker
- Centos安装Docker
- windows安装Docker
- Docker中运行Redis
- Docker中运行MongoDB
- Centos 8 运行MySQL 5.7并远程连接
- Centos MySQL无法显示中文
Docker简介
Docker和容器化技术简介
我先用比较专业的术语说明一下Docker和容器。如果感觉枯燥,可以跳转到大白话理解Docker
章节。
容器技术:和传统的虚拟化以及半虚拟化相比,容器运行时不需要模拟层(emulation layer)和管理层(hypervisor layer),而是使用操作系统的系统调用接口。这降低运行单个容器所需的开销,也使得宿主机中可以运行更多的容器
但是容器本身比较复杂,不易安装,管理和自动化也比较困难,Docker就是为了改变这个而诞生的。
Docker:Docker是一个能够把开发的应用程序自动部署到容器的开源引擎。
Docker在虚拟化的容器中增加了一个应用程序部署引擎,该引擎的目标是提供一个轻量级的环境来运行开发者的程序,并且能非常方便地将程序部署到测试环境以及生产环境。
Docker的核心组件
Docker的核心组件分为如下四部分
- Docker客户端和服务器
- Docker镜像
- Registry
- Docker容器
Docker客户端和服务器
Docker是一个C/S架构的程序,Docker只需向Docker服务器或者是守护进程发送请求,服务器或守护进程将完成所有工作并返回结果。可以在同一台宿主机上运行Docker守护进程和客户端,也可以在不同的宿主机上运行。
Docker镜像
镜像是基于联合(Union)文件系统的一种层次的结构,由一系列指令一步一步构建出来
例如:
- 添加一个文件
- 执行一个文件
- 打开一个端口
可以简单地把镜像当作容器的的源代码。镜像体积很小,非常便携
Registry
Docker用Registry来保存和用户构建的镜像。Registry分为公有和私有两种。Docker公司运营的公共Registry叫做Docker Hub,类似于Github。用户可以在上面分享并保存自己的镜像,也可以在Docker Hub上保存自己的私有镜像。
除此之外,用户可以架设自己的私有的Registry用来保存自己的镜像。
Docker容器
Docker可以帮助用户构建和部署容器,用户只需要把自己的应用程序或服务打包放进容器。容器是基于镜像启动起来的。它们之间的关系可以这么简单理解:镜像就好比是程序的代码,它是死的,只有当代码运行起来我们才能称之为程序。代码是死的,程序是活的。代码和程序可以看作是一个东西,只是对应着不同的状态而已。
同理,我们可以这么认为:镜像是Docker生命周期中的构建或打包阶段,而容器则是启动或执行阶段。镜像没有启动的时候,它是镜像,是死的,镜像启动以后,它就是容器,它是活的。
大白话理解Docker
前我们来看看Docker的这个看起来憨憨的图标,可能一下子就能明白Docker的含义了。
大轮船运载着很多集装箱,将集装箱运往世界各地,集装箱里装满了货物。
Docker也可以理解为是这么一艘大轮船,Docker的容器可以看作是集装箱,唯一不同的可能就是:Docker这个轮船的集装箱上装的是软件,
每个容器都包含了一个软件镜像。集装箱可以被创建,打开,关闭,销毁。镜像也可以被创建、启动、关闭、重启以及销毁。
Docker不管容器中装了什么,它只负责管理。用户不仅可以将自己的应用程序打包进这个容器,还能将该程序所需要的运行环境一并打包进入,比如将Web服务器,数据库,jdk等都装进去。
用户再将自己的这个容器作为镜像发布到registry上,就好像是把集装箱放到了大轮船上,运往了世界各地。接着,来自世界各地的人都可以通过registry下载你发布的镜像。
回想过去软件开发场景,如果你要运行一个Java web的程序,你首先得配置一个Servlet容器,比如Tomcat。然后你还得安装jdk,程序中使用的数据库是MySQL,你还得配置MySQL,经过繁琐的配置,你终于将自己本机的运行环境和程序的运行环境配置一致,程序才有可能成功运行起来。
而现在,你只需要安装Docker就可以了。只需要在Docker中启动你下载的镜像即可,镜像中已经将程序的运行环境整个打包进去了,你无需配置环境,只需要一句docker run
命令就可以运行应用程序了。
官网的这张图能很好地阐述这几者的关系
- 使用
docker build
命令,我们可以构建自己的镜像,并将其推送到registry - 使用
docker run
命令,我们可以运行本机的镜像,镜像一旦被运行起来,就变成了容器 - 使用
docker pull
命令,我们可以从registry中下载镜像
安装Docker
Centos安装Docker
- 卸载旧版本Docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 安装所需软件包
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
- 设置阿里云仓库
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装 Docker Engine-Community
默认是安装最新版本的 Docker Engine-Community 和 containerd
yum install docker-ce docker-ce-cli containerd.io
- 启动Docker
systemctl start docker
- 运行hello-world示例
运行成功截图
windows安装Docker
对于Windows用户,直接下载并安装Docker Desktop即可,然后在Windows的命令行工具中运行和管理容器。
直接搜索Docker就可以找到Windows Desktop,然后就可以下载并安装了。
Window命令行工具推荐使用Windows Terminal。可以自由配置主题,字体等内容。
Windows Terminal
比如我的Windows Terminal。还可以使用很多Linux原生指令。
安装好Docker Desktop以后启动即可。
当Docker Desktop运行起来,就可以使用Docker了
可以先在Windows Terminal中查看docker的相关信息
输入docker info
需要注意的是:由于Docker的registry
是在国外。就和Maven的仓库一样,所以直接进行访问都比较慢,因此需要配置镜像加速,来加速访问。
一般都会选择使用阿里云的镜像加速,我们首先需要注册一个阿里云的账号,然后找到容器镜像服务,复制镜像加速的地址。
复制上面那个地址,然后在Docker Window Desktop设置中,进行如下配置,然后重新进行启动:
然后打开命令行工具输入docker info
命令查看是否配置成功
如下所示,如果在Registry Mirrors
中有你配置的地址,则说明配置成功。
Docker中运行Redis
首先是从registry中pull一个image
PS C:\Users\simon> docker pull redis
Using default tag: latest
latest: Pulling from library/redis
no matching manifest for windows/amd64 10.0.18363 in the manifest list entries
PS C:\Users\simon>
报了一个错:no matching manifest for windows/amd64 10.0.18363 in the manifest list entries
打开Docker Desktop的页面,将图中圈出来的地方,由false改为true,然后重启即可。
第一步:通过docker pull redis
命令获取redis的镜像
PS C:\Users\simon> docker pull redis
Using default tag: latest
latest: Pulling from library/redis
6ec7b7d162b2: Pull complete
1f81a70aa4c8: Pull complete
968aa38ff012: Pull complete
884c313d5b0b: Pull complete
6e858785fea5: Pull complete
78bcc34f027b: Pull complete
Digest: sha256:0f724af268d0d3f5fb1d6b33fc22127ba5cbca2d58523b286ed3122db0dc5381
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
PS C:\Users\simon>
第二步:通过docker images
命令来查看本地镜像,发现的确存在了一个redis的镜像,则可以开始启动redis镜像了。
PS C:\Users\simon> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest ef47f3b6dc11 5 days ago 116MB
PS C:\Users\simon>
第三步:启动redis镜像。在启动之前,需要先了解一些命令行的参数。
参数说明:
-d
,后台运行容器-e
,设置环境变量--expose / -p
宿主端口:容器端口--name
,指定容器名称--link
,链接不同容器-v
宿主目录:容器目录,挂载磁盘卷
运行命令:docker run --name redis -d -p 6379:6379 redis
-p 6379:6379: 前面表示主机的端口,后表示容器的端口。相当于就是将主机的6379端口映射到容器的6379端口,这样,访问主机的6379端口,相当于就是访问容器的6379端口。
PS C:\Users\simon> docker run --name redis -d -p 6379:6379 redis
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (windows/amd64) and no specific platform was requested
4dbbdebb372f205f89d8f6382d3e0de800db36c62496cbf71f5977b231af7af8
启动以后,再使用docker ps
查看是否有正在运行的容器。发现的确是有一个名为redis的容器正在运行。
PS C:\Users\simon> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4dbbdebb372f redis "docker-entrypoint.s…" 13 seconds ago Up 7 seconds 0.0.0.0:6379->6379/tcp redis
PS C:\Users\simon>
第四步:进入redis的客户端
使用docker exec -it redis redis-cli
命令
需要注意的是:docker exec -it redis redis-cli
等于docker exec -i -t redis redis-cli
。该命令表示要在容器redis
中执行redis-cli
命令
docker exec
表示在运行的容器中执行指令-i
表示容器中的STDIN(标准输出)是开启的,这样我们才能通过交互式shell观察输出-t
表示要为创建的容器分配一个伪终端
进入客户端以后,我们就可以开始使用Redis了。
PS C:\Users\simon> docker exec -it redis redis-cli
127.0.0.1:6379> hset user1 username zhangefei
(integer) 1
127.0.0.1:6379> hset user1 age 28
(integer) 1
127.0.0.1:6379> hget user1 username
"zhangefei"
127.0.0.1:6379> hmset user2 username guanyu age 30
OK
127.0.0.1:6379> hget user2 username
"guanyu"
127.0.0.1:6379>
Docker中运行MongoDB
下载镜像
docker pull mongo
运行
docker run --name mongo -p 27017:27017 -v /d/Environment/docker/mongdb/data:/data/db -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=admin -d mongo
# /d/Environment/docker/mongdb/data对应着Windows的路径: D:\Environment\docker\mongdb\data
- -d —— 后台运行
- –name —— 实例运行后的名字 myredis
- -p6379:6379 —— 端口映射,冒号前面是windows下的端口,后面是虚拟机的端口
- -v /d/Environment/docker/mongdb/data —— 保存数据的位置(宿主机位置)
- /data/db对应着mongoDB中的位置
进入mongo容器
docker exec -it mongo bash
登录进mongo数据库
mongo -u admin -p admin
Centos 8 运行MySQL 5.7并远程连接
Windows Docker Desktop 莫名其妙崩了,目前还没解决
PS C:\Windows\System32> docker restart redis
Error response from daemon: Cannot restart container redis: hcsshim::CreateComputeSystem 4dbbdebb372f205f89d8f6382d3e0de800db36c62496cbf71f5977b231af7af8: The virtual machine could not be started because a required feature is not installed.
(extra info: {"SystemType":"container","Name":"4dbbdebb372f205f89d8f6382d3e0de800db36c62496cbf71f5977b231af7af8","Owner":"docker","LayerFolderPath":"C:\\ProgramData\\Docker\\lcow\\4dbbdebb372f205f89d8f6382d3e0de800db36c62496cbf71f5977b231af7af8","Layers":[{"ID":"cf5a4248-e646-58ae-8f73-921f795cf1d5","Path":"C:\\ProgramData\\Docker\\lcow\\809a96ec2ead0117711afb21a51b7b7797e4380d88f5b364cf3a63f922aed215\\layer.vhd"},{"ID":"431da3b5-47fd-5e41-9bcc-b836f165875f","Path":"C:\\ProgramData\\Docker\\lcow\\ad80724d7a4d4977f47939fea72a3726886390a44b457644ca3be526d883c60b\\layer.vhd"},{"ID":"3a411480-a41b-5df4-90d6-f9547b1b2084","Path":"C:\\ProgramData\\Docker\\lcow\\260f8ce4c38d725359e5529dcfcf481ef2ceec0c1db87b833e66b382b556bfef\\layer.vhd"},{"ID":"3e697837-c0e3-55d5-92bb-224eed85e996","Path":"C:\\ProgramData\\Docker\\lcow\\974d36c8ceeb58fc2d4bfb70c2b9459fa20692d2c2982b468f37feb80f3add05\\layer.vhd"},{"ID":"4ed39680-5d80-56a6-a9d4-f12c2f5ef753","Path":"C:\\ProgramData\\Docker\\lcow\\8585c10a62becbcab74b0d5242222b8c026c56fd66ac3737e34db25401fc0c30\\layer.vhd"},{"ID":"9bf55231-05c5-55eb-a2e7-098dd177f32f","Path":"C:\\ProgramData\\Docker\\lcow\\66175dde37e4c85e3715394a9c5792ef9369d673123386657cd89eef6e7c036e\\layer.vhd"}],"MappedDirectories":[{"HostPath":"C:\\ProgramData\\Docker\\volumes\\5cabcf45f835c8c3d8edf41813b25faf7c70aef9e406a0ad3c82f0404ef3e513\\_data","ContainerPath":"/tmp/gcs/4dbbdebb372f205f89d8f6382d3e0de800db36c62496cbf71f5977b231af7af8/binds/data","ReadOnly":false,"BandwidthMaximum":0,"IOPSMaximum":0,"CreateInUtilityVM":true,"LinuxMetadata":true}],"HvPartition":true,"EndpointList":["AEC40654-9203-4C88-A31E-D0E32617785A"],"HvRuntime":{"ImagePath":"C:\\Program Files\\Linux Containers","LinuxInitrdFile":"initrd.img","LinuxKernelFile":"kernel"},"AllowUnqualifiedDNSQuery":true,"ContainerType":"linux","TerminateOnLastHandleClosed":true})
PS C:\Windows\System32>
所以,只好在centos中使用Docker了
下载镜像
docker pull mysql:5.7
在宿主机上创建文件夹用于对mysql中的数据进行数据持久化
如果不对Docker中运行的容器进行数据持久化,容器中产生的数据会随着容器的结束而结束,如果容器被删掉了,里面的数据也会被删掉。
在宿主机中创建conf
文件夹和data
文件夹。并在conf文件夹中新建一个my.cnf
文件。记住其路径。
[root@simon docker-data]# ls
mysql5.7 nginx
[root@simon docker-data]# cd mysql5.7
[root@simon mysql5.7]# ll
total 0
[root@simon mysql5.7]# mkdir conf
[root@simon mysql5.7]# mkdir data
[root@simon mysql5.7]# ll
total 0
drwxr-xr-x. 2 root root 6 Feb 9 16:51 conf
drwxr-xr-x. 2 root root 6 Feb 9 16:51 data
[root@simon mysql5.7]#
运行mysql
docker run --name mysql5.7 -p 3307:3306 \
-v /root/docker-data/mysql5.7/data:/var/lib/mysql/ \
-v /root/docker-data/mysql5.7/conf/my.cnf:/etc/mysql/my.cnf \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 \
--default-authentication-plugin=mysql_native_password
[root@simon data]# docker exec -it mysql5.7 bash #进入docker容器,并进入bash命令
root@1b6c1bf82caf:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.33 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> grant all privileges on *.* to 'root'@'%' ; #给root用户所有权限
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
root@1b6c1bf82caf:/# read escape sequence # 按Ctrl+P+Q退出容器,容器不关闭
[root@simon data]# docker ps #查看正在运行的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b6c1bf82caf mysql:5.7 "docker-entrypoint.s…" 48 minutes ago Up 48 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp mysql5.7
[root@simon data]#
退出容器以后可以发现,在宿主机上已经有了mysql中的数据
然后在服务器的控制台中打开3307端口的防火墙
使用navicate远程连接数据库
我在Navicat中创建了kings数据库,并新建了一个user表
在服务器端也能查询到相应数据
Centos MySQL无法显示中文
发现了一个问题:在Centos 的mysql中无法识别中文
我在navicat中创建表的时候用了中文,在服务器中却无法显示。name使用的是utf8编码
我在mysql中查看了一下字符编码,发现其字符编码不管是server还是client都不是utf8。
show variables like'character_set_%';
先退出mysql,然后停止容器。
mysql> exit
Bye
root@1b6c1bf82caf:/# read escape sequence
[root@simon conf]# docker stop mysql5.7
mysql5.7
[root@simon conf]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@simon conf]#
最开始在启动的时候我已经指定了mysql的配置文件(my.cnf
)在宿主机中的路径。
打开my,cnf
[root@simon conf]# pwd
/root/docker-data/mysql5.7/conf
[root@simon conf]# ls
my.cnf
[root@simon conf]#vim my.cnf
然后在my.cnf
中添加如下内容。主要是图中圈出部分,用于设置数据库的编码。
[mysqld]
lower_case_table_names=1
character_set_server=utf8
[client]
default-character-set=utf8
重启容器,重新进入mysql。
docker restart mysql5.7 #重启容器
docker exec -it mysql5.7 bash #进入容器
#进入mysql
root@1b6c1bf82caf:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.33 MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
发现字符集已经修改过了。
再次查询发现已经能正常显示中文了。
mysql> show tables;
+-----------------+
| Tables_in_kings |
+-----------------+
| user |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from user;
+--------+
| name |
+--------+
| 张三 |
+--------+
1 row in set (0.01 sec)
mysql>