构建Docker镜像实战——nginx、sshd、systemctl、tomcat和mysql叠罗汉

前言:Nginx是一款轻量级的Web服务器。Tomcat是一款免费开源的轻量级Web服务器,在中小型企业和并发访问量不高的场合普遍使用,是开发和调试JSP程序的首选。MySQL是当下最流行的关系型数据库,LNMP是相应的Linux系统下的Nginx、MySQL、PHP相结合而构建成的动态网站服务器架构。以上这些都可以使用Dockerfile文件的方式来创建其Docker镜像

文章目录

  • 一、概念回顾
  • 二、构建Nginx镜像
    • 1.下载基础镜像
    • 2.建立工作目录
    • 3.创建并编写Dockerfile文件
    • 4.编写执行脚本内容
    • 5.生成镜像
    • 6.访问测试
    • 7.删除none镜像
  • 三、构建SSH镜像
  • 四、构建Systemctl镜像
  • 五、构建Tomcat镜像
  • 六、构建Mysql镜像
    • 总结

一、概念回顾

  • Docker在运行一个容器之前,需要以镜像作为基础环境,可以说镜像是整个Docker容器创建的关键,而创建镜像的三种方法中基于Dockerfile创建的方法使用最为灵活
  • Dockerfile可以看作是被Docker程序所解释翻译的脚本,是由一组命令集合而成,每条命令都应对一条操作指令,由Docker翻译为Linux下的具体命令。用户可以通过自定义其内容来快速创建镜像。Dockerfile文件有自己严格的格式需要遵循,每行只支持一条指令,先回顾一下Dockerfile的操作指令
    构建Docker镜像实战——nginx、sshd、systemctl、tomcat和mysql叠罗汉_第1张图片

二、构建Nginx镜像

  • Nginx是一款轻量级的Web服务器,也是一款优秀的反向代理服务器。下面使用Dockerfile文件的方式来创建带有Nginx服务的Docker镜像

1.下载基础镜像

  • 首先下载一个创建Nginx镜像的基础镜像——centos镜像
[root@promote ~]# docker pull centos:7
7: Pulling from library/centos
ab5ef0e58194: Pull complete 
Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c
Status: Downloaded newer image for centos:7
docker.io/library/centos:7

2.建立工作目录

  • 创建工作目录
[root@promote opt]# mkdir nginx
[root@promote opt]# cd nginx/
[root@promote nginx]# 

3.创建并编写Dockerfile文件

  • 提前准备好Nginx源码包
[root@promote nginx]# ls
nginx-1.12.2.tar.gz  
  • 可以根据具体的Nginx安装过程来编写Dockerfile文件
[root@promote nginx]# vim Dockerfile
#设置基础镜像
FROM centos:7
#维护该镜像的用户信息
MAINTAINER this is nginx
#安装相关依赖包及跟新一下YUM源
RUN yum -y update
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
#建立一个用户便于管理
RUN useradd -M -s /sbin/nologin nginx
#解压Nginx源码包
ADD nginx-1.12.2.tar.gz /opt/nginx
WORKDIR /opt/nginx/nginx-1.12.2
#编译安装nginx
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
#开启80和443端口
EXPOSE 80
EXPOSE 443
#修改Nginx配置文件,以非daemon方式启动
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
#复制服务启动脚本并设置权限
ADD run.sh /run.sh
RUN chmod 755 /run.sh
#启动容器时执行脚本
CMD ["/run.sh"]

4.编写执行脚本内容

[root@promote nginx]# vim run.sh
/usr/local/ningx/sbin/nginx

5.生成镜像

[root@promote nginx]# docker build -t nginx:new .
  • 此时该文件下已经准备好
[root@promote nginx]# ls
Dockerfile  nginx-1.12.2.tar.gz  run.sh
  • 查看镜像,已经生成成功
[root@promote nginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               new                 da2dc936fbe2        6 minutes ago       584MB
  • 基于这个镜像生成容器
[root@promote nginx]# docker run -d -P nginx:new 
d61a57d476e9461620dfc13e51f1b74176841f8b21b0c2db136525fbc144266d
[root@promote nginx]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS                                           NAMES
d61a57d476e9        nginx:new           "/run.sh"                4 seconds ago       Up 4 seconds                  0.0.0.0:32772->80/tcp, 0.0.0.0:32771->443/tcp   reverent_sanderson

6.访问测试

  • 随机生成的端口号为32772,在本机上网访测试
    构建Docker镜像实战——nginx、sshd、systemctl、tomcat和mysql叠罗汉_第2张图片

7.删除none镜像

  • 在执行dockerfile之后,会生成很多none镜像,还有没用的容器,所以可以写一个脚本,批量删除
[root@promote ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               new                 da2dc936fbe2        44 minutes ago      584MB
                            7ee665a981f9        44 minutes ago      568MB
                            aff304f45fae        54 minutes ago      568MB
                            11cc498ab0a8        54 minutes ago      568MB
                            acef6bf742b1        About an hour ago   568MB
  • 编写脚本
[root@promote ~]# vi none.sh
docker ps -a | grep "Exited" | awk '{print $1}' | xargs docker stop
docker ps -a | grep "Exited" | awk '{print $1}' | xargs docker rm
docker images | grep none | awk '{print $3}' | xargs docker rmi

//执行

[root@promote ~]# chmod +x none.sh 
[root@promote ~]# ./none.sh

[root@promote ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               new                 da2dc936fbe2        49 minutes ago      584MB
centos              7                   5e35e350aded        5 months ago        203MB

[root@promote ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS              PORTS                                           NAMES
d61a57d476e9        nginx:new           "/run.sh"               39 minutes ago      Up 39 minutes       0.0.0.0:32772->80/tcp, 0.0.0.0:32771->443/tcp   reverent_sanderson

三、构建SSH镜像

  • 我们可以基于做好的nginx镜像继续构建
[root@promote ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               new                 da2dc936fbe2        53 minutes ago      584MB
centos              7                   5e35e350aded        5 months ago        203MB
  • 创建一个sshd目录,在目录下配置dockerfile
[root@promote ~]# cd /opt/
[root@promote opt]# ls
nginx  rh
[root@promote opt]# mkdir sshd
[root@promote opt]# cd sshd/
[root@promote sshd]# vi Dockerfile
#基于nginx镜像
FROM nginx:new
#作者信息
MAINTAINER the sshd
#安装环境依赖包
RUN yum -y install openssh* net-tools lsof telnet passwd
#输入密码
RUN echo '1234' | passwd --stdin root
#关闭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
#关闭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
#设置端口
EXPOSE 22
#-D为守护进程
CMD ["/usr/sbin/sshd" , "-D"]
[root@promote sshd]# docker build -t sshd:new .   //构建
  • 构建完成后,即可创建容器并进行交互登录
[root@promote sshd]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sshd                new                 05cd33f18623        29 seconds ago      792MB
[root@promote sshd]# docker run -d -P sshd:new 
687a47563b0c7c34ccfb251a8c369f93bfd7282349adc981e4e11c2216b9fdf9
[root@promote sshd]# docker ps -a
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                        PORTS                                                                  NAMES
687a47563b0c        sshd:new            "/usr/sbin/sshd -D"   12 seconds ago      Up 11 seconds                 0.0.0.0:32775->22/tcp, 0.0.0.0:32774->80/tcp, 0.0.0.0:32773->443/tcp   priceless_benz
[root@promote sshd]# ssh localhost -p 32775   //22端口外部是32775
The authenticity of host '[localhost]:32775 ([::1]:32775)' can't be established.
RSA key fingerprint is SHA256:ftjQl37s8nIQ4dKbQ/xK2IcLde+JHPBquQCsAz8rzYQ.
RSA key fingerprint is MD5:7c:62:e1:3b:39:96:3d:db:20:6d:12:e0:a6:37:69:fa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:32775' (RSA) to the list of known hosts.
root@localhost's password:     //密码是1234
[root@687a47563b0c ~]# cd /
[root@687a47563b0c /]# ls
anaconda-post.log  dev  home  lib64  mnt  proc  run     sbin  sys  usr
bin                etc  lib   media  opt  root  run.sh  srv   tmp  var
//交互登录成功

四、构建Systemctl镜像

  • 构建完ssh镜像后,进入容器,但是却发现不能使用systemctl命令,所以还需要进行构建
[root@687a47563b0c ~]# systemctl status sshd
Failed to get D-Bus connection: Operation not permitted
  • 继续基于ssh镜像构建,创建systemctl目录并配置dockerfile
[root@promote systemctl]# vim Dockerfile
#基于ssh镜像
FROM sshd:new
#设置环境变量
ENV container docker
#进入指定目录,用for循环遍历目录下所有文件并删除指定文件
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemed-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/anaconde.target.wants/*;
#创建挂载的卷
VOLUME [ "/sys/fs/cgroup" ]
#执行初始化命令
CMD ["/usr/sbin/init"]
[root@promote systemctl]# docker build -t local/c7_systemd:latest . //执行
  • 构建完成后,生成镜像,这里需要注意的是以root进入容器时需要添加–privileged做提取,并且将宿主机下的cgroup挂载到docker中的cgroup
[root@promote systemctl]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
local/c7_systemd    latest              47c463d2e276        20 seconds ago      792MB

[root@promote systemctl]# docker run --privileged -it -v /sys/fs/cgroup:/sys/fs/cgroup:ro local/c7_systemd:latest /sbin/init
systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization docker.
Detected architecture x86-64.

Welcome to CentOS Linux 7 (Core)!

Set hostname to .
[  OK  ] Reached target Swap.
[  OK  ] Reached target Paths.
[  OK  ] Reached target Local File Systems.
[  OK  ] Created slice Root Slice.
[  OK  ] Listening on Journal Socket.
[  OK  ] Listening on Delayed Shutdown Socket.
[  OK  ] Created slice System Slice.
[ INFO ] Update UTMP about System Boot/Shutdown is not active.
[DEPEND] Dependency failed for Update UTMP about System Runlevel Changes.
Job systemd-update-utmp-runlevel.service/start failed with result 'dependency'.
[  OK  ] Reached target System Initialization.
[  OK  ] Listening on D-Bus System Message Bus Socket.
[  OK  ] Reached target Sockets.
[  OK  ] Started Daily Cleanup of Temporary Directories.
[  OK  ] Reached target Timers.
[  OK  ] Reached target Slices.
[  OK  ] Reached target Basic System.
[  OK  ] Reached target Multi-User System.
Startup finished in 14ms.
  • 此时已经进入加载状态,再打开一个端口
[root@promote ~]# docker ps -a
CONTAINER ID        IMAGE                     COMMAND                  CREATED              STATUS                     PORTS                                                                  NAMES
b9db7efe0111        local/c7_systemd:latest   "/sbin/init"             About a minute ago   Up About a minute          22/tcp, 80/tcp, 443/tcp                                                mystifying_borg
[root@promote ~]# docker exec -it b9db7efe0111 bash
[root@b9db7efe0111 /]# systemctl status sshd
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:sshd(8)
           man:sshd_config(5)
//可以看到能够使用

五、构建Tomcat镜像

  • 创建tomcat目录,准备所需要的软件包
[root@promote opt]# mkdir tomcat
[root@promote opt]# cd tomcat/
[root@promote tomcat]# ls
apache-tomcat-8.5.16.tar.gz  jdk-8u91-linux-x64.tar.gz
  • 编写Dockerfile
[root@promote tomcat]# vim Dockerfile
#基于基础镜像
FROM local/c7_systemd:latest
#作者信息
MAINTAINER the tomcat
#解压
ADD jdk-8u91-linux-x64.tar.gz /usr/local
#指定目录并添加环境变量
WORKDIR /usr/local
RUN mv jdk1.8.0_91 /usr/local/java
ENV JAVA_HOME /usr/local/java
ENV JAVA_BIN /usr/local/java/bin
ENV JAVA_HOME /usr/local/java/jre
ENV PATH $PATH:/usr/local/java/bin:/usr/local/java/jre/bin
ENV CLASSPATH /usr/local/java/jre/bin:/usr/local/java/lib:/usr/local/java/jre/lib/charsets.jar
#解压并指定目录
ADD apache-tomcat-8.5.16.tar.gz /usr/local
WORKDIR /usr/local
#修改tomcat名称方便管理
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat8
#指定端口
EXPOSE 8080
#启动tomcat
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]
[root@promote tomcat]# docker build -t tamcat:new .   //执行
  • 构建容器并启动tomcat


[root@promote tomcat]# docker run -d --name temcat1 -p 1234:8080 -it tamcat:new 
b57ca0a40362888a092ddea84edaec3d2473c234eebf8548c792df7fd6c5e5b3
[root@promote tomcat]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tamcat              new                 53b6aa1498fe        18 seconds ago      1.55GB
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                      PORTS                                                                  NAMES
b57ca0a40362        tamcat:new                "/usr/local/tomcat8/…"   13 seconds ago      Up 12 seconds               22/tcp, 80/tcp, 443/tcp, 0.0.0.0:1234->8080/tcp                        temcat1
  • 访问tomcat
    构建Docker镜像实战——nginx、sshd、systemctl、tomcat和mysql叠罗汉_第3张图片

六、构建Mysql镜像

  • 准备好所需要的包
[root@promote mysql]# ls
mysql-boost-5.7.20.tar.gz
[root@promote mysql]# vim Dockerfile
#基于tomcat镜像
FROM tamcat:new
#安装依赖包
RUN yum -y install ncurses  ncurses-devel bison cmake make gcc gcc-c++
#创建用户
RUN useradd -s /sbin/nologin mysql
#解压以及指定工作目录并进行手工编译
ADD mysql-boost-5.7.20.tar.gz /usr/local/src
WORKDIR /usr/local/src/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-PERDSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=boost \
-DWITH_SYSTEMD=1 && make && make install
#设置权限
RUN chown -R mysql:mysql /usr/local/mysql
#删除原有的配置文件并复制新的
RUN rm -rf /etc/my.cnf
ADD my.cnf /etc
RUN chown mysql:mysql /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=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
#方便system管理
RUN cp  /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
#指定端口
EXPOSE 3306
#设置启动脚本
RUN echo -e "#!/bin/sh \nsystemctl enable mysqld" > /run.sh
RUN chmod +x /run.sh
RUN sh /run.sh
CMD ["init"]

[root@promote mysql]# docker build -t mysql.all .  //执行
  • 生成容器并进入
[root@promote mysql]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql.all           latest              73dc50d25356        37 minutes ago      11.2GB
[root@promote mysql]# docker run -d -P --privileged mysql.all
be838f5752b547e2990a8d5bb4ec3c0013a842e634f44a8927fe45905a3410af
[root@promote mysql]# docker ps -a
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                           PORTS                                                                                                                    NAMES
be838f5752b5        mysql.all                 "/usr/local/tomcat8/…"   4 seconds ago       Up 3 seconds                     0.0.0.0:32800->22/tcp, 0.0.0.0:32799->80/tcp, 0.0.0.0:32798->443/tcp, 0.0.0.0:32797->3306/tcp, 0.0.0.0:32796->8080/tcp   pensive_ishizaka
[root@promote mysql]# docker exec -it be838f5752b5 /bin/bash
  • 进入数据库并设置权限
mysql> grant all privileges on *.* to 'root'@'%' identified by '1234';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
  • 在另一台虚拟机上远程登录数据库
[root@localhost sys]# mysql -uroot -p1234 -h 192.168.170.133 -P 32797
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
。。。省略部分内容
mysql> create database ku;
Query OK, 1 row affected (0.00 sec)
  • 登录成功

  • 总结

  • Dockerfile可以看作是被Docker程序所解释翻译的脚本,是由一组命令集合而成,每条命令都应对一条操作指令,由Docker翻译为Linux下的具体命令

你可能感兴趣的:(docker,dockerfile)