admin管理员组

文章数量:1601618

在开启本章之前,我想对k8s弃用Docker一事表达一下自己的看法。我是无意中在CSDN上看到有关报道的。然后就看到评论下面有很多人在说什么Docker凉凉,既然弃用了,就刚好不用学之类的话。
容器早在Docker诞生之前就已经存在了,只是一直不温不火而已,是Docker的诞生让整个容器市场突然变得一片火热。可以翻翻历史,看看当初Docker这个项目诞生的时候是有多火,多么受人关注。可以看看当初Docker是怎么凭一己之力扛起整个容器市场的,又怎么凭一己之力来对抗整个云计算产业的竞争和围剿。
正是为了对抗Docker的火热以及在容器市场的垄断。2014 年, Google 公司突然宣告了一个名叫 Kubernetes 项目的诞生。而后,Google、RedHat 等开源基础设施领域玩家们,共同牵头发起了一个名为 CNCF(Cloud Native Computing Foundation)的基金会。这个基金会的目的其实很容易理解:它希望,以 Kubernetes 项目为基础,建立一个由开源基础设施领域厂商主导的、按照独立基金会方式运营的平台级社区,来对抗以 Docker 公司为核心的容器商业生态。

最后,Docker这家公司算是失败了,但是Docker这个项目事实上却仍然是整个容器市场的一个规范。
不管K8s是否弃用Docker,你觉得该不该了解一下Docker呢?
这让我想到了保时捷和大众的关系。保时捷这个汽车品牌被大众收购了,但是大众的第一大股东却是保时捷控股。保时捷控股失去了保时捷这个汽车品牌,却成为了大众汽车背后的第一大股东。当年,保时捷和大众的战争能说谁输谁赢呢?

文章目录

  • 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就是为了改变这个而诞生的。

DockerDocker是一个能够把开发的应用程序自动部署到容器的开源引擎
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/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文件夹中新建一个myf文件。记住其路径。

[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/myf:/etc/mysql/myf \
-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的配置文件(myf)在宿主机中的路径。

打开my,cnf

[root@simon conf]# pwd
/root/docker-data/mysql5.7/conf
[root@simon conf]# ls
myf
[root@simon conf]#vim myf

然后在myf中添加如下内容。主要是图中圈出部分,用于设置数据库的编码。

[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>

本文标签: 大白话阿里镜像WindowsDocker