Docker 面试题2则
早上接到群里小伙伴求助面试题,据说20K以上.面试题如下
题⽬1:编写Dockerfile 编写 Dockerfile ,构建⼀个Docker镜像(不能包含 MySQL 服务端程序),完成以下需求:
镜像中包含⼀个 shell 脚本,容器启动后每隔 30s 收集 MySQL 数据库当前的连接数,将数据同时输出⾄ /data/log ⽂件(⽇志可以持久化保存)及标准输出中
数据库IP、端⼝、⽤户及密码可以在容器启动时通过 -e 指定环境变量来修改
要求容器启动后可以使⽤ docker logs container_name 和 docker exec -i -t container_name tail -f /data/log 两种⽅式查看⽇志信息
每次输出的信息格式如下 [2019-01-01 00:00:00] Number of active DB connections is 10.
题⽬2:编写Docker-compose 编写 docker-compose.yml 脚本,使⽤题⽬1中构建的镜像及 MySQL 镜像启动服务
看到他的题,第一反应是考的分层打镜像,然后二进制安装mysql,最后再用docker-compose实现数据库启动.群里其他小伙伴也是这个反应.
仔细读了几遍题目后才发现并不是这样.我们来梳理下要求.
我们先启动一个数据库容器
docker pull mysql:5.6.38
docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root123 mysql:5.6.38
尝试连接下数据库
root@k8s-master-01:/opt/k8s-data/dockerfile/mysql# mysql -uroot -proot123 -h192.168.31.201 -P3306 -e "show databases;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
获取下数据库的连接数
root@k8s-master-01:/opt/k8s-data/dockerfile/mysql# mysql -uroot -proot123 -h192.168.31.201 -P3306 -e "show status like 'Threads_connected';"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 1 |
+-------------------+-------+
可以看到值取到了.那么我们把这个值交给一个变量即可
root@k8s-master-01:/opt/k8s-data/dockerfile/mysql# a=`mysql -uroot -proot123 -h192.168.31.201 -P3306 -e "show status like 'Threads_running';"|grep Threads_connected|awk '{print $2}'`
mysql: [Warning] Using a password on the command line interface can be insecure.
root@k8s-master-01:/opt/k8s-data/dockerfile/mysql# echo $a
1
这个很简单,分两步
count=``mysql -uroot -proot123 -h192.168.31.201 -P3306 -e "show status like 'Threads_connected';"|grep Threads_running|awk '{print $2}'`
echo $count >>/data/log
2. 启动容器的时候
```bash
docker run -d -v /data:/data docker-image
通过$1 $2 $3的位置参数将值传递给脚本
#!/bin/bash
DO=1
while [ "$DO" -gt 0 ] ;do
MYSQL_IP=$1
MYSQL_PORT=$2
MYSQL_PASSWD=$3
count=`mysql -uroot -p${MYSQL_PASSWD} -h${MYSQL_IP} -P${MYSQL_PORT} -e 'show status'|grep Threads_connected|awk '{print $2}'`
echo " $count." >> /data/log
sleep 30
done
通过-e将参数传递给容器,此时在容器中可以打印出传递进来参数的值
docker run -d -e MYSQL_IP="192.168.31.201" -e MYSQL_PORT="3306" -e MYSQL_PASSWD="root123" -v /data:/data container-image
在脚本中添加一行
echo $count >> /dev/stdout
修改后的count.sh
#!/bin/bash
DO=1
while [ "$DO" -gt 0 ] ;do
MYSQL_IP=$MYSQL_IP
MYSQL_PORT=$MYSQL_PORT
MYSQL_PASSWD=$MYSQL_PASSWD
MYSQL_USER=$MYSQL_USER
TIME=`date +"%Y-%m-%d %H:%M:%S"`
count=`mysql -u${MYSQL_USER} -p${MYSQL_PASSWD} -h${MYSQL_IP} -P${MYSQL_PORT} -e 'show status'|grep Threads_connected|awk '{print $2}'`
echo "[${TIME}] Number of active DB connections is $count." >> /data/log
echo "[${TIME}] Number of active DB connections is $count." >> /dev/stdout
sleep 30
done
Dockerfile
FROM centos:7.9.2009
RUN rm -f /etc/yum.repos.d/*
ADD mysql-community-client-5.7.31-1.el7.x86_64.rpm /root
ADD mysql-community-common-5.7.31-1.el7.x86_64.rpm /root
ADD mysql-community-libs-5.7.31-1.el7.x86_64.rpm /root
ADD Centos-7.repo /etc/yum.repos.d/
ADD count.sh /root/
RUN yum install /root/mysql-community-*.rpm -y
ENV MYSQL_USER "root"
ENV MYSQL_IP ""
ENV MYSQL_PORT "3306"
ENV MYSQL_PASSWD ""
ENTRYPOINT ["/root/count.sh"]
build.sh
#!/bin/bash
Version=$1
docker build -t harbor.intra.com/baseimages/mysql-threads:v${Version} .
docker push harbor.intra.com/baseimages/mysql-threads:v${Version}
version: '3'
services:
mysql:
image: mysql:5.6.38
restart: always
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root123
mysql-threads:
image: harbor.intra.com/baseimages/mysql-threads:v12
build:
context: .
dockerfile: Dockerfile
restart: always
environment:
MYSQL_IP: "192.168.31.104"
MYSQL_PORT: "3306"
MYSQL_PASSWD: "root123"
volumes:
- /data:/data
最后的效果