Dockerfile实战
在上一次的创建Docker镜像中有使用Dockerfile来创建镜像,在生产环境中也经常使用Dockerfile来创建定制镜像。在Dockerfile中主要的写法与shell脚本类似。但是最重要的是如何正确的启动镜像,使容器运行起来。
这里我准备了几个需求实战,有兴趣的可以看一看。
一、使用Dockerfile制作nginx镜像
首先我们来制作一个nginx的镜像。我在/opt/目录下创建了一个ng的目录,并在该目录下写了如下的Dockerfile:
制作镜像的目录下包含了源码包、启动脚本和Dockerfile。
#选择基础镜像centos7
FROM centos:7
#更新yum环境
RUN yum -y update
#安装编译工具
RUN yum install -y pcre* zlib-devel gcc gcc-c++ make
#添加一个无家目录和无法登陆的nginx用户
RUN useradd -M -s /sbin/nologin nginx
#将源码包解压复制到容器中的/opt目录下
ADD nginx-1.12.2.tar.gz /opt
#指定工作目录
WORKDIR /opt/nginx-1.12.2
#开始编译和make
RUN ./configure --prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-http_flv_module
RUN make && make install
#nginx对外提供80和443端口
EXPOSE 80
EXPOSE 443
#关闭以守护进程的形式启动nginx,不加这句话到配置文件中容器无法正常运行!!!
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
#添加启动脚本
ADD run.sh /run.sh
RUN chmod +x /run.sh
#开启容器时运行启动脚本
CMD ["/run.sh"]
启动脚本则是:
run.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx
使用:
docker build -t nginx01:web .
创建nginx镜像。
启动nginx镜像:
docker run -d --name web01 -P 1b493316d6f7
查看随机端口:docker ps -a
打开游览器查看:
二、制作tomcat镜像
我们开支制作tomcat的镜像,在一个目录下添加jdk、tomcat源码包并写一个Dockerfile。
Dockerfile的内容:
#基于基础镜像
FROM centos:7
#作者信息
MAINTAINER bbs
#添加jdk到/opt目录中
ADD jdk-8u201-linux-x64.rpm /opt
#指定工作目录,并安装jdk
WORKDIR /opt
RUN rpm -i jdk-8u201-linux-x64.rpm
#添加环境变量
RUN echo "export JAVA_HOME=/usr/java/jdk1.8.0_201-amd64" >> /etc/profile
RUN echo "export CLASSPATH=\$JAVA_HOME/lib/tools.jar:\$JAVA_HOME/lib/dt.jar" >> /etc/profile
RUN echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile
#解压tomcat源码包
ADD apache-tomcat-9.0.16.tar.gz /usr/local
#开启tomcat容器内部的8080端口
EXPOSE 8080
#修改tomcat的名称便于管理
RUN mv /usr/local/apache-tomcat-9.0.16/ /usr/local/tomcat
#建立启动命令的软连接以便系统识别
RUN ln -s /usr/local/tomcat/bin/startup.sh /usr/bin/
RUN ln -s /usr/local/tomcat/bin/shutdown.sh /usr/bin/
#使用ENTRYPOINT启动tomcat
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
查看镜像:
启动tomcat镜像:
成功访问tomcat。
三、制作sshd镜像,可以通过ssh远程进入容器
这次镜像只需要写一个Dockerfile就可以了。
#基于基础镜像
FROM centos:7
#镜像作者信息
MAINTAINER bbs
#更新系统yum源
RUN yum -y update
#安装openssh、网络工具、远程连接、密码等工具
RUN yum -y install openssh* net-tools lsof telnet passwd
#标准性输入root密码
RUN echo '111111' | passwd --stdin root
#关闭ssh的pam认证
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#创建非对称秘钥对
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
#关闭ssh的pam会话模块
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
#创建ssh的工作目录并且设置权限
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
#开启容器的22端口
EXPOSE 22
#以守护进程的方式开启ssh
CMD ["/usr/sbin/sshd" , "-D"]
运行镜像,并登录到容器内部:
四、创建systemctl可用镜像
在之前的ssh镜像上创建新的镜像。因为ssh的镜像中无法用systemctl进行管理。
依旧编写Dockerfile
#基于之前创建的ssh:01的镜像
FROM ssh:01
#设置环境变量 container和docker
ENV container docker
#执行先到指定目录,进行for循环遍历目录下所有文件并删除指定的文件。之后进行一系列的删除
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*; \
rm -f /etc/systemd/system/*.wants/*; \
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*; \
rm -f /lib/systemd/system/anaconda.target.wants/*;
#创建一个挂载卷
VOLUME [ "/sys/fs/cgroup" ]
#执行初始化命令
CMD ["/usr/sbin/init"]
之后我们创建容器,这里需要注意的是root身份进入容器需要提权操作"–privileged",并且以只读的形式将宿主机下的cgroup挂载到docker中的cgroup。
docker run -d --name sys --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro -it 3da77b6fb458 /sbin/init
五、安装mysql数据库镜像
首先准备好源码包、Dockerfile文件和数据库配置文件。
FROM centos:7
MAINTAINER bsy
RUN yum -y update
RUN yum install -y gcc gcc-c++ cmake ncurses ncurses-devel bison make
#添加用户
RUN useradd -s /sbin/nologin mysql
ADD mysql-boost-5.7.20.tar.gz /usr/local
WORKDIR /usr/local/mysql-5.7.20
RUN cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=boost \
-DWITH_SYSTEMD=1
RUN make && make install
RUN chown -R mysql:mysql /usr/local/mysql
#删除原有的配置文件
RUN rm -rf /etc/my.cnf
#添加新的配置文件
ADD my.cnf /etc/my.cnf
#设置环境变量
ENV PATH /usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
WORKDIR /usr/local/mysql/
#初始化数据库
RUN bin/mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
RUN cp usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
EXPOSE 3306
#配置启动脚本
ADD echo -e "#!/bin/bash \nsystemctl enable mysqld" > /run.sh
RUN chmod +x /run.sh
RUN sh /run.sh
CMD ["init"]
创建镜像,并运行容器。
docker run -d --name my02 -P --privileged 5f6b34b9f8f5
进入容器:
dcoker exec -it f75d6323ef12 /bin/bash
为数据库设置远程登录的权限:
mysql> grant all privileges on *.* to 'root'@'%' identified by '111111';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
在其他操作系统上远程登录数据库:
[root@localhost sys]# mysql -uroot -p111111 -h 192.168.80.106 -P 32769
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.20 Source distribution
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
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> create database bbs;
Query OK, 1 row affected (0.00 sec)
mysql> use bbs;
Database changed
mysql> exit
Bye
说明已经成功登录数据库并且可以正常使用。