目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

X

Docker自定义镜像

自定义镜像的常见方式

  • 基于Docker Commit制作镜像
  • 基于dockerfile制作镜像,Dockerfile方式为主流的制作镜像方式。

镜像的分层结构

  • 多个容器层共享同一个镜像层
  • 对容器的任何改动都是发生在容器层
  • 容器层是可写可读,而镜像层只读
  • class : object
[root@master ~]# docker history mycentos:v2
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
6179c08f8204        17 minutes ago      /bin/sh -c yum install -y net-tools             100MB               
11f381c5e640        17 minutes ago      /bin/sh -c #(nop) COPY file:8eda00bfac1c94e7…   0B                  
25cc0d469386        17 minutes ago      /bin/sh -c #(nop) WORKDIR /home/soulboy         0B                  
a6624f371c02        17 minutes ago      /bin/sh -c echo "正在构建镜像!!!"                     0B                  
3059d7b5e9eb        17 minutes ago      /bin/sh -c #(nop)  MAINTAINER XD 123456@qq.c…   0B                  
5e35e350aded        3 weeks ago         /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B                  
<missing>           3 weeks ago         /bin/sh -c #(nop) ADD file:45a381049c52b5664…   203MB       

基于Docker Commit制作镜像

# 对容器进行内容变更
[root@master ~]# docker run -it centos:7 /bin/bash
[root@fef3ea9fbcf0 /]# mkdir /home/soulboy 
[root@fef3ea9fbcf0 /]# yum install -y net-tools

# 对修改进行保存
[root@master ~]# docker commit -a "dudulong" -m "mkdir&&net-tools" fef3ea9fbcf0 mycentos:v1
sha256:78cf18af254e37d88164e96db0b25386922ff38b868a28b897c4559a1095ab51

# 删除当前容器
[root@master ~]# docker rm -f fef3ea9fbcf0
fef3ea9fbcf0

# 机遇新镜像(commit生成的)启动容器
[root@master ~]# docker run -itd mycentos:v1 /bin/bash
07c23a9cbd4f130bd621262b87ecb0966476a487582074175393cd2a89023587

# 进入新容器(验证)
[root@master ~]# docker exec -it 07c23a9cbd4f130bd621262b87ecb0966476a487582074175393cd2a89023587 /bin/bas
[root@07c23a9cbd4f /]# ls /home/       
soulboy
[root@07c23a9cbd4f /]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 12  bytes 976 (976.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

基于dockerfile制作镜像

dockerfile

# this is a dockerfile
FROM centos:7
MAINTAINER XD 123456@qq.com
RUN echo "正在构建镜像!!!"
WORKDIR /home/soulboy
COPY 123.txt /home/soulboy
RUN yum install -y net-tools


# 基于~~~~dockerfile构建镜像  
[root@master ~]# docker build -t mycentos:v2 .
Complete!
Removing intermediate container 4c77f4b0473c
 ---> 6179c08f8204
Successfully built 6179c08f8204
Successfully tagged mycentos:v2

# 验证镜像v2
[root@master ~]# docker run -it mycentos:v2 /bin/bash
[root@18e750313a81 soulboy]# pwd		#进入容器就自动切换到指定工作目录下
/home/soulboy
[root@18e750313a81 soulboy]# ls	#发现已经把目标文件复制到指定路径下
123.txt

Dockerfile基础指令

FROM	#哪个镜像
MAINTAINER	#作者
COPY	#后面跟相对路径;不能是绝对路径
ADD	#复制+解压
WORKDIR	#指定工作目录
ENV	#设置环境变量
EXPOSE	#暴露容器端口
RUN	#执行命令:作用于镜像层(镜像构建中)
CMD	#在容器启动的时候执行,作用于容器层,dockerfifile里有多条时只允许执行最后一条;容器启动后执行默认的命令或者参数,允许被修改。CMD本身也可以作为参数,传递给ENTRYPOINT命令后面。前提是ENTRYPOINT采用的是exec格式的命令。
ENTRYPOINT	#在容器启动的时候执行,作用于容器层,dockerfifile里有多条时只允许执行最后一条,ENTRYPOINT优于CMD,docker run后面的参数可以覆盖 CMD后面的命令。
命令格式:
	shell命令格式:RUN yum install -y net-tools
	exec命令格式:RUN ["yum","install","-y","net-tools"]

构建JDK&Tomcat镜像

[root@master java]# ls
apache-tomcat-8.5.35.tar.gz  dockerfile  jdk-8u211-linux-x64.tar.gz

# dockerfile文件如下
[root@master java]# cat dockerfile 
FROM centos:7 
ADD jdk-8u211-linux-x64.tar.gz /usr/local 
RUN mv /usr/local/jdk1.8.0_211 /usr/local/jdk 
ENV JAVA_HOME=/usr/local/jdk 
ENV JRE_HOME=$JAVA_HOME/jre 
ENV CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH 
ENV PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH 
ADD apache-tomcat-8.5.35.tar.gz /usr/local 
RUN mv /usr/local/apache-tomcat-8.5.35 /usr/local/tomcat 
EXPOSE 8080 
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]

# 构建镜像过程
[root@master java]# docker build -t mycentos:jdk .
Successfully built c41cd3fd2268
Successfully tagged mycentos:jdk

# 启动容器(基于mycentos:jdk)
[root@master java]# mkdir /docker/java/root 
[root@master java]# echo "hello world!" > /docker/java/root/index.html
[root@master java]# docker run -itd -p 80:8080 -v /docker/java/root:/usr/local/tomcat/webapps/ROOT mycentos:jdk /bin/bash
555a56919263ee51256d98e35dea8a998d393caa684bc59e508db0e1176b25af

# 访问http://192.168.31.201/
hello world!

构建Nginx镜像

# 文件如下
[root@master nginx]# ls
dockerfile  nginx-1.16.0.tar.gz  nginx_install.sh

# 安装nginx的shell脚本
[root@master nginx]# cat nginx_install.sh 
#!/bin/bash
yum install -y gcc gcc-c++ make pcre pcre-devel zlib zlib-devel 
cd /usr/local/nginx-1.16.0
./configure --prefix=/usr/local/nginx && make && make install

# dockerfile
[root@master nginx]# cat dockerfile 
FROM centos:7
ADD nginx-1.16.0.tar.gz /usr/local 
COPY nginx_install.sh /usr/local 
RUN sh /usr/local/nginx_install.sh 
EXPOSE 80

# 生成Nginx镜像
[root@master nginx]# docker build -t mycentos:nginx .
 ---> b9d019985162
Successfully built b9d019985162
Successfully tagged mycentos:nginx

# 启动容器(在容器种nginx是以daeon方式启动,退出容器时,nginx程序也会随之停止,使用前台永久运行 /usr/local/nginx/sbin/nginx -g "daemon off;")
docker run -itd -p 80:80 mycentos:nginx /usr/local/nginx/sbin/nginx -g "daemon off;"
[root@master nginx]# docker run -itd -p 80:80 mycentos:nginx /usr/local/nginx/sbin/nginx -g "daemon off;"
2cea91ffd31aea999fec8f832a6ea27dc3aee690debc3904c727ca2f52c6a124

# 访问http://192.168.31.201/
	Welcome to nginx!

构建Redis镜像

# 文件结构如下
[root@master redis2]# ls
dockerfile  redis-4.0.9.tar.gz  redis_install.sh

# redis安装脚本
[root@master redis2]# cat redis_install.sh 
#!/bin/bash 
yum install -y gcc gcc-c++ make openssl openssl-devel 
cd /home/redis-4.0.9 
make && make PREFIX=/usr/local/redis install 
mkdir -p /usr/local/redis/conf/ 
cp /home/redis-4.0.9/redis.conf /usr/local/redis/conf/ 
sed -i '69s/127.0.0.1/0.0.0.0/' /usr/local/redis/conf/redis.conf 
sed -i '88s/protected-mode yes/protected-mode no/' /usr/local/redis/conf/redis.conf

# dockerfile
[root@master redis2]# cat dockerfile 
FROM centos:7 
ADD redis-4.0.9.tar.gz /home 
COPY redis_install.sh /home 
RUN sh /home/redis_install.sh 
ENTRYPOINT /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf

# 制作镜像
[root@master redis2]# docker build -t mycentos:redis .
 ---> 012fd0093f26
Successfully built 012fd0093f26
Successfully tagged mycentos:redis

# 启动容器
[root@master redis2]# docker run -itd -p 6380:6379 mycentos:redis #6380是宿主机端口,6379是容器的端口

# 进入容器
[root@master redis2]# docker exec -it a42f1207 /bin/bash

# 使用redis-cli远程连接redis
[root@master redis2]# /usr/local/redis/bin/redis-cli -p 6380

快速部署mysql数据库并初始化(构建mysql镜像)

hub.docker.mysql

# 拉取镜像
[root@master redis2]# docker pull mysql:5.7

# 目录结构
[root@master mysql]# ls
dockerfile  init.sql

# 初始化sql语句
[root@master mysql]# cat init.sql 
-- 建库 create database `db_student`; 
SET character_set_client = utf8; 
use db_student; 
-- 建表 
drop table if exists `user`; 
CREATE TABLE user ( 
	id tinyint(5) zerofill auto_increment not null comment '学生学号', 
	name varchar(20) default null comment '学生姓名', 
	age tinyint default null comment '学生年龄', 
	class varchar(20) default null comment '学生班级', 
	sex char(5) not null comment '学生性别', 
	unique key (id) 
)engine=innodb charset=utf8; 
-- 插入数据 
insert into user values('1','小明','15','初三','男'); 
insert into user values('2','小红','13','初二','女'); 
insert into user values('3','小东','14','初一','男');

# dockerfile
[root@master mysql]# cat dockerfile 
FROM mysql:5.7 
WORKDIR /docker-entrypoint-initdb.d 
ENV LANG=C.UTF-8 
ADD init.sql .

# 构建镜像
[root@master mysql]# docker build -t my-mysql:5.7 .
 ---> 8921287b2399
Successfully built 8921287b2399
Successfully tagged my-mysql:5.7

# 启动容器
[root@master mysql]# docker run --name some-mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123 -d my-mysql:5.7 
da00b587b821dfa76bdbe7ef250a44d7fd5aa4d9f75d1e6d05a92c4965a04895

# 进入容器验证是否初始化数据库
[root@master mysql]# docker exec -it some-mysql /bin/bash
root@34370a9c7279:/docker-entrypoint-initdb.d# mysql -uroot -p123
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.28 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, 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> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_student         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use db_student;
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> select * from user;
+-------+--------+------+--------+-----+
| id    | name   | age  | class  | sex |
+-------+--------+------+--------+-----+
| 00001 | 小明   |   15 | 初三   | 男  |
| 00002 | 小红   |   13 | 初二   | 女  |
| 00003 | 小东   |   14 | 初一   | 男  |
+-------+--------+------+--------+-----+
3 rows in set (0.00 sec)

作者:Soulboy