0%

以前我们要做一个实验,需要安装虚拟机,安装需要耗费一定的时间,就算是复制虚拟机,也会占用大量磁盘空间。现在我们只需要创建一个CentOS的Docker容器就可以了,比较方便。

拉取操作系统镜像

这里我们采用CentOS

1
docker pull centos

centos镜像拉取到本地后,我们查看一下

1
2
3
docker images 
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 67fa590cfc1c 6 weeks ago 202MB

运行容器并进入容器

1
2
docker run -it centos bash
[root@ca6a84a514c2 /]#

修改yum源

如果是在公司内网环境,需要改为内网的源。如果是国外的源,也可以换成国内的源。
具体方法请参考 将Centos7的yum源更换为国内阿里云的源

安装所需软件

安装ip工具

1
yum install -y iproute

安装ssh软件

1
yum install -y openssh-server openssh-clients

会有ssh相关软件被拷贝到/usr/sbin目录

需要软件sshd的绝对路径去启动sshd服务,不然会报如下错误。

1
2
./sshd
sshd re-exec requires execution with an absolute path

输入全路径执行命令,继续出现错误,如下:

1
2
3
4
5
/usr/sbin/sshd
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
sshd: no hostkeys available -- exiting.

执行sshd-keygen命令解决上述问题

1
2
3
4
/usr/sbin/sshd-keygen 
Generating SSH2 RSA host key: [ OK ]
Generating SSH2 ECDSA host key: [ OK ]
Generating SSH2 ED25519 host key: [ OK ]

给root生成一个密码

1
2
3
4
5
6
passwd root
Changing password for user root.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.

启动sshd服务

1
2
3
/usr/sbin/sshd
[root@ca6a84a514c2 sbin]# ps -ef | grep sshd
root 108 1 0 09:14 ? 00:00:00 /usr/sbin/sshd

验证sshd服务

1
2
3
4
5
ssh root@localhost
root@localhost's password:
Last failed login: Sun Sep 29 09:16:59 UTC 2019 from localhost on ssh:notty
There were 3 failed login attempts since the last successful login.
Connection to localhost closed.

会遇到连不上去的问题,这时,需要修改/etc/ssh/sshd_config配置。

把里面的UsePAM yes改为UsePAM no

杀掉之前sshd进程后,再次启动

1
2
/usr/sbin/sshd
WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several problems.

这时就可以成功登录了。

1
2
3
root@localhost
root@localhost's password:
Last login: Sun Sep 29 09:20:41 2019 from localhost

生成一个新的镜像

退出容器,并查看容器id

1
2
3
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca6a84a514c2 centos "bash" 34 minutes ago Exited (255) 11 seconds ago musing_goodall

生成一个新的镜像

1
2
docker commit ca6a84a514c2 basic_centos 
sha256:2f965d1db627968f66bf968db7c052f1dec02b84a0b508ef896b3c8d93f97fb7

查看镜像

1
2
3
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
basic_centos latest 2f965d1db627 26 seconds ago 284MB

运行镜像

1
docker run -dit basic_centos /usr/sbin/sshd -D

此时,就可以通过ssh client连接上去了。

pip安装依赖的时候报错,pg_config executable not found, 所以需要在mac上安装postgresql。

1
brew install postgresql

如果出现Updating Homebrew并且卡住了,请参考

安装过程中,有可能会遇到操作文件权限不够的情况,添加一下权限就可以了。

安装成功,将有如下提示:

1
2
3
4
5
6
7
8
9
10
11
To migrate existing data from a previous major version of PostgreSQL run:
brew postgresql-upgrade-database

To have launchd start postgresql now and restart at login:
brew services start postgresql
Or, if you don't want/need a background service you can just run:
pg_ctl -D /usr/local/var/postgres start
==> Summary
🍺 /usr/local/Cellar/postgresql/11.5_1: 3,189 files, 35.6MB
==> `brew cleanup` has not been run in 30 days, running now...
Pruned 4 symbolic links and 58 directories from /usr/local

经常会遇到分组求前几名的问题。比如,求每个班级中总分排名前三的学生。

我们通过如下实验看看怎么解决这个问题。

创建学生分数表

1
2
3
4
5
6
7
CREATE TABLE `score` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`name` varchar(255) DEFAULT NULL COMMENT '学生姓名',
`class` varchar(255) DEFAULT NULL COMMENT '班级',
`score` int(11) DEFAULT NULL COMMENT '总分',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建若干条数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DELIMITER //
DROP PROCEDURE IF EXISTS batchInsert;
CREATE PROCEDURE batchInsert(n INT)
BEGIN
DECLARE i INT;
SET i = 0;
WHILE i < n DO
INSERT INTO score(name, class, score) VALUES
(substring(MD5(RAND()), 1, 10), CONCAT('G', ROUND(RAND() * 9)), ROUND(RAND() * 100));
SET i = i + 1;
END WHILE;
END
//
DELIMITER ;
CALL batchInsert(50);

TOP N

HAVING子句中的< 3表示取前两条。

1
2
3
4
5
SELECT s1.class, s1.score FROM score s1
LEFT JOIN score s2 ON s1.class = s2.class AND s1.score <= s2.score
GROUP BY s1.class, s1.score
HAVING COUNT(1) < 3
ORDER BY s1.class, s1.score DESC;

如果是取TOP 1,那就不能用这个自连接了,不然效率非常低下。还是得用MIN, MAX函数来解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class   score
G0 66
G0 17
G1 96
G1 92
G2 87
G2 83
G3 67
G3 32
G4 94
G4 37
G5 99
G5 74
G6 40
G7 98
G7 78
G8 100
G8 93
G9 99
G9 92