SourceURL:file:///home/student/Desktop/容器技术.doc
镜像编排
Dockerfile 详解
指令 | 说明 |
FROM | 指定基础镜像(scratch 代表空镜像) |
RUN | 在容器内执行命令,可以写多条 |
ADD | 把文件拷贝到容器内,如果文件是 tar.xx 格式,会自动解压 |
COPY | 把文件拷贝到容器内,不会自动解压 |
ENV | 设置启动容器的环境变量 |
WORKDIR | 设置启动容器的默认工作目录(唯一) |
CMD | 容器默认的启动参数(唯一) |
ENTRYPOINT | 容器默认的启动命令(唯一) |
USER | 启动容器使用的用户(唯一) |
EXPOSE | 使用镜像创建的容器默认监听使用的端口号/协议 |
# 编写 Dockerfile
[root@docker ~]# mkdir myimg
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
CMD ["/bin/ls", "-l"]
# 创建镜像
[root@docker ~]# docker build -t img:v1 myimg/
[root@docker ~]# docker images
# 创建容器
[root@docker ~]# docker run -it --rm img:v1
# 传递参数命令,覆盖 CMD 执行
[root@docker ~]# docker run -it --rm img:v1 id
uid=0(root) gid=0(root) groups=0(root)
语法案例(2)
# ENTRYPOINT 与 CMD 执行方式为 ${ENTRYPOINT} ${@-${CMD}}
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
ENTRYPOINT ["echo"]
CMD ["/bin/ls", "-l"]
# 创建镜像
[root@docker ~]# docker build -t img:v2 myimg/
# CMD 做为参数传递,在容器内执行了 echo '/bin/ls -l'
[root@docker ~]# docker run -it --rm img:v2
/bin/ls -l
# CMD 被替换,在容器内执行了 echo id
[root@docker ~]# docker run -it --rm img:v2 id
语法案例(3)
# 制作测试文件
[root@docker ~]# tar -cf myimg/myfile.tar -C /etc hosts issue
# 编辑Dockerfile
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
COPY myfile.tar /tmp/ # 新添加
ADD myfile.tar /var/tmp/ # 新添加
CMD ["/bin/bash"]
# 创建镜像
[root@docker ~]# docker build -t img:v3 myimg/
# 运行测试
[root@docker ~]# docker run -it --rm img:v3
# 使用 COPY 进来的文件还是 tar 包
bash-4.4$ tree /tmp
# 使用 ADD 添加的文件已经被解压了
bash-4.4$ tree /var/tmp
语法案例(4)
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
COPY myfile.tar /tmp/
ADD myfile.tar /var/tmp/
RUN touch /tmp/file1 # 新添加
USER nobody # 新添加
RUN touch /tmp/file2 # 新添加
CMD ["/bin/bash"]
# 创建镜像
[root@docker ~]# docker build -t img:v4 myimg/
# 运行测试
[root@docker ~]# docker run -it --rm img:v4
# USER 指令设置使用 nobody 用户运行容器
bash-4.4$ id
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)
# USER 指令前创建的文件是 root 权限,之后是 USER 用户权限
bash-4.4$ ls -l /tmp/file?
-rw-r--r-- 1 root root 0 Feb 5 05:25 /tmp/file1
-rw-r--r-- 1 nobody nobody 0 Feb 5 05:25 /tmp/file2
语法案例(5)
# 编辑Dockerfile
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
COPY myfile.tar /tmp/
ADD myfile.tar /var/tmp/
RUN touch /tmp/file1
USER nobody
RUN touch /tmp/file2
ENV TZ="Asia/Shanghai" # 新添加
EXPOSE 12345/tcp # 新添加
CMD ["/bin/bash"]
# 创建镜像
[root@docker ~]# docker build -t img:v5 myimg/
# 运行测试
[root@docker ~]# docker run -it --rm img:v5
# 环境变量可以直接调用
bash-4.4$ echo ${TZ}
Asia/Shanghai
bash-4.4$ date +%T
10:50:18
# 在其他终端查看
[root@docker ~]# docker ps
CONTAINER ID IMAGE ... ... STATUS PORTS
14b669a75a95 img:v5 ... ... Up 1 minutes 12345/tcp
语法案例(6)
# 编辑Dockerfile
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
COPY myfile.tar /tmp/
ADD myfile.tar /var/tmp/
RUN touch /tmp/file1
USER nobody
RUN touch /tmp/file2
ENV TZ="Asia/Shanghai"
EXPOSE 12345/tcp
WORKDIR /tmp # 新添加
CMD ["/bin/bash"]
# 创建镜像
[root@docker ~]# docker build -t img:v6 myimg/
......
# 运行测试
[root@docker ~]# docker run -it --rm img:v6
# 环境变量可以直接调用
bash-4.4$ pwd
/tmp
apache 镜像
- 拷贝 info.php 测试文件到 /root/ 目录下
[root@server s4]# rsync -av public/info.php 192.168.88.32:/root/
手工部署
# 创建容器
[root@docker ~]# docker run -it --name httpd mylinux:latest
# 安装软件包
[root@975fb53cb155 /]# dnf install -y httpd php && dnf clean all
# 在其他终端添加测试页面
[root@docker ~]# echo 'Welcome to The Apache.' >index.html
[root@docker ~]# docker cp index.html httpd:/var/www/html/
[root@docker ~]# docker cp info.php httpd:/var/www/html/
# 修改配置文件
[root@975fb53cb155 /]# vim /etc/httpd/conf.modules.d/00-mpm.conf
11: LoadModule mpm_prefork_module ... ... # 去掉注释
23: # LoadModule mpm_event_module ... ... # 注释配置
# 设置环境变量
[root@975fb53cb155 /]# export LANG=C
# 启动服务
[root@975fb53cb155 /]# /usr/sbin/httpd -DFOREGROUND
制作镜像
# 编写 dockerfile 文件
[root@docker ~]# mkdir apache
[root@docker ~]# tar -czf apache/myweb.tar.gz index.html info.php
[root@docker ~]# docker cp httpd:/etc/httpd/conf.modules.d/00-mpm.conf apache/00-mpm.conf
[root@docker ~]# vim apache/Dockerfile
FROM mylinux:latest
RUN dnf install -y httpd php && dnf clean all
COPY 00-mpm.conf /etc/httpd/conf.modules.d/00-mpm.conf
ADD myweb.tar.gz /var/www/html/
ENV LANG=C
EXPOSE 80/tcp
WORKDIR /var/www/html
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
[root@docker ~]# docker build -t myhttpd:latest apache
......
验证测试
# 查看镜像并创建容器
[root@docker ~]# docker images myhttpd:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
myhttpd latest c1e854cde1f4 About a minute ago 299MB
[root@docker ~]# docker run -itd --name web myhttpd:latest
cc2b82ad0367172c344c7207def94c4c438027c60859e94883e440b53a860a93
# 查看容器地址并访问验证
[root@docker ~]# docker inspect web |grep -i IPAddress
[root@docker ~]# curl http://172.17.0.2/info.php
<pre>
Array
(
[REMOTE_ADDR] => 172.17.0.1
[REQUEST_METHOD] => GET
[HTTP_USER_AGENT] => curl/7.61.1
[REQUEST_URI] => /info.php
)
php_host: 2fbc8c132f7f
1229
[root@docker ~]# docker rm -f $(docker ps -aq)
nginx 镜像
- 拷贝 public/nginx-1.22.1.tar.gz 到 docker 主机
[root@server s4]# rsync -av public/nginx-1.22.1.tar.gz 192.168.88.32:/root/
手工部署
# 创建容器
[root@docker ~]# docker run -itd --name web mylinux:latest
a1448547a12c15c8b1d1defa76e96f63f0f68ccb6bdeb59958ee57fc5dfac11e
# 拷贝 nginx 源码包到容器内
[root@docker ~]# docker cp nginx-1.22.1.tar.gz web:/
Successfully copied 1.08MB to web:/
# 解压源码
[root@docker ~]# docker exec -it web bash
[root@a1448547a12c /]# tar zxf nginx-1.22.1.tar.gz
[root@a1448547a12c /]# cd /nginx-1.22.1
# 安装依赖包和编译工具
[root@a1448547a12c /]# dnf install -y openssl pcre
[root@a1448547a12c /]# dnf install -y openssl-devel pcre-devel gcc make
[root@a1448547a12c /]# dnf clean all
# 编译安装
[root@a1448547a12c nginx-1.22.1]# ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module
[root@a1448547a12c nginx-1.22.1]# make
[root@a1448547a12c nginx-1.22.1]# make install
# 设置默认首页
[root@a1448547a12c nginx-1.22.1]# echo 'Nginx is running !' >/usr/local/nginx/html/index.html
# 添加环境变量
[root@a1448547a12c nginx-1.22.1]# export PATH=${PATH}:/usr/local/nginx/sbin
# 启动服务
[root@a1448547a12c nginx-1.22.1]# nginx -g "daemon off;"
制作镜像
[root@docker ~]# mkdir nginx
[root@docker ~]# vim nginx/Dockerfile
FROM mylinux:latest
ADD nginx-1.22.1.tar.gz /
WORKDIR /nginx-1.22.1
RUN dnf install -y openssl pcre
RUN dnf install -y openssl-devel pcre-devel gcc make
RUN dnf clean all
RUN ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module
RUN make
RUN make install
RUN echo 'Nginx is running !' >/usr/local/nginx/html/index.html
ENV PATH=${PATH}:/usr/local/nginx/sbin
WORKDIR /usr/local/nginx
EXPOSE 80/tcp
CMD ["nginx", "-g", "daemon off;"]
[root@docker ~]# mv nginx-1.22.1.tar.gz nginx/
[root@docker ~]# docker build -t mynginx:latest nginx
......
验证测试
# 查看镜像并创建容器
[root@docker ~]# docker images mynginx:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx latest 645dd2d9a8ec 3 minutes ago 480MB
[root@docker ~]# docker run -itd --name nginx mynginx:latest
e440b53a860a93cc2b82ad0367172c344c7207def94c4c438027c60859e94883
# 查看容器地址并访问验证
[root@docker ~]# docker inspect nginx |grep -i IPAddress
[root@docker ~]# curl http://172.17.0.2/
Nginx is running !
[root@docker ~]# docker rm -f $(docker ps -aq)
多阶段镜像
[root@docker ~]# docker rmi mynginx:latest
[root@docker ~]# vim nginx/Dockerfile
# 第一阶段编译程序
FROM mylinux:latest as builder
ADD nginx-1.22.1.tar.gz /
WORKDIR /nginx-1.22.1
RUN dnf install -y openssl-devel pcre-devel gcc make
RUN ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module
RUN make
RUN make install
RUN echo 'Nginx is running !' >/usr/local/nginx/html/index.html
# 第二阶段最终镜像
FROM mylinux:latest
RUN dnf install -y pcre openssl && dnf clean all
COPY --from=builder /usr/local/nginx /usr/local/nginx
ENV PATH=${PATH}:/usr/local/nginx/sbin
WORKDIR /usr/local/nginx
EXPOSE 80/tcp
CMD ["nginx", "-g", "daemon off;"]
[root@docker ~]# docker build -t mynginx:latest nginx
[root@docker ~]# docker images mynginx:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx latest d9cedbd4a042 10 seconds ago 268MB
php-fpm 镜像
手工部署
[root@docker ~]# docker run -it --name myphp mylinux:latest
[root@cbcf3d90c02e /]# dnf install -y php-fpm
# 修改配置文件
[root@cbcf3d90c02e /]# vim /etc/php-fpm.d/www.conf
38: listen = 127.0.0.1:9000
# 创建目录,并授权
[root@cbcf3d90c02e /]# mkdir /run/php-fpm
[root@cbcf3d90c02e /]# chown -R nobody.nobody /var/log/php-fpm /run/php-fpm
# 使用 sudo 且换用户
[root@cbcf3d90c02e /]# dnf install -y sudo
[root@cbcf3d90c02e /]# sudo -u nobody /bin/bash
# 使用 nobody 启动服务
bash-4.4$ /usr/sbin/php-fpm --nodaemonize
[04-Sep-2023 09:58:01] NOTICE: [pool www] 'user' directive is ignored when FPM is not running as root
[04-Sep-2023 09:58:01] NOTICE: [pool www] 'group' directive is ignored when FPM is not running as root
[04-Sep-2023 09:58:01] NOTICE: fpm is running, pid 1
[04-Sep-2023 09:58:01] NOTICE: ready to handle connections
[04-Sep-2023 09:58:01] NOTICE: systemd monitor interval set to 10000ms
制作镜像
# 编写 dockerfile 文件
[root@docker ~]# mkdir php
[root@docker ~]# vim php/Dockerfile
FROM mylinux:latest
RUN dnf install -y php-fpm && dnf clean all && \
mkdir -p /run/php-fpm && \
chown -R nobody.nobody /run/php-fpm /var/log/php-fpm && \
sed -ri 's,^(listen =).*,\1 127.0.0.1:9000,' /etc/php-fpm.d/www.conf
USER nobody
EXPOSE 9000/tcp
CMD ["/usr/sbin/php-fpm", "--nodaemonize"]
[root@docker ~]# docker build -t php-fpm:latest php
验证测试
# 查看镜像并创建容器
[root@docker ~]# docker images php-fpm:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
php-fpm latest b2404bd119b0 48 seconds ago 268MB
[root@docker ~]# docker run -itd --name php php-fpm:latest
6eeff6af4a6469c298944b2bdd2ba69f32ebcbc6cb683a0a05af4eefbf90e8c1
# 验证服务
[root@docker ~]# docker exec -it php /bin/bash
# 验证用户
bash-4.4$ id
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)
# 我们无法直接调用 php 服务,可以通过查看进程验证服务
bash-4.4$ ps -ef
UID PID PPID C STIME CMD
nobody 1 0 0 16:13 php-fpm: master process (/etc/php-fpm.conf)
nobody 7 1 0 16:13 php-fpm: pool www
nobody 8 1 0 16:13 php-fpm: pool www
nobody 17 0 0 16:13 /bin/bash
nobody 19 17 0 16:13 ps -ef
bash-4.4$ exit
[root@docker ~]# docker rm -f $(docker ps -aq)
docker 私有仓库
主机清单
主机名 | ip地址 | 最低配置 |
registry | 192.168.88.30 | 1CPU,1G内存 |
registry 安装
# 在 registry 上安装私有仓库
[root@registry ~]# vim /etc/yum.repos.d/docker.repo
[Docker]
name=Rocky Linux $releasever - Docker Packages
baseurl="ftp://192.168.88.240/rpms"
enabled=1
gpgcheck=0
[root@registry ~]# dnf makecache
[root@registry ~]# dnf install -y docker-distribution
# 启动私有仓库,并设置开机自启动
[root@registry ~]# systemctl enable --now docker-distribution
客户端配置
- 所有 docker 节点都需要配置
[root@docker ~]# vim /etc/hosts
192.168.88.30 registry
# 修改配置文件
[root@docker ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://registry:5000", "其他镜像仓库"],
"insecure-registries":["registry:5000"]
}
# 重启服务生效
[root@docker ~]# systemctl restart docker
[root@docker ~]# docker info
上传镜像
# 给镜像设置标签
[root@docker ~]# docker tag mylinux:latest registry:5000/img/mylinux:latest
# 上传镜像
[root@docker ~]# docker push registry:5000/img/mylinux:latest
# 上传 rockylinux 镜像
[root@docker ~]# docker tag rockylinux:8 registry:5000/img/mylinux:8
[root@docker ~]# docker push registry:5000/img/mylinux:8
# 上传 httpd 镜像
[root@docker ~]# docker tag myhttpd:latest registry:5000/library/myhttpd:latest
[root@docker ~]# docker push registry:5000/library/myhttpd:latest
# 上传 nginx 镜像
[root@docker ~]# docker tag mynginx:latest registry:5000/library/mynginx:latest
[root@docker ~]# docker push registry:5000/library/mynginx:latest
# 上传 php-fpm 镜像
[root@docker ~]# docker tag php-fpm:latest registry:5000/library/php-fpm:latest
[root@docker ~]# docker push registry:5000/library/php-fpm:latest
验证测试
- 查看镜像名称: curl http://仓库IP:5000/v2/_catalog
- 查看镜像标签: curl http://仓库IP:5000/v2/镜像路径/tags/list
- 使用易读格式: python3 -m json.tool
# 查看仓库中所有镜像的名称
[root@docker ~]# curl http://registry:5000/v2/_catalog
{"repositories":["img/mylinux","library/myhttpd","library/mynginx","library/php-fpm"]}
# 易读格式显示镜像名称
[root@docker-0002 ~]# curl -s http://registry:5000/v2/_catalog |python3 -m json.tool
{
"repositories": [
"img/mylinux",
"library/myhttpd",
"library/mynginx",
"library/php-fpm"
]
}
# 查看某一镜像的所有标签
[root@docker ~]# curl http://registry:5000/v2/img/mylinux/tags/list
{"name":"img/mylinux","tags":["latest","8"]}
# 易读格式查看镜像标签
[root@docker ~]# curl -s http://registry:5000/v2/img/mylinux/tags/list |python3 -m json.tool
{
"name": "img/mylinux",
"tags": [
"latest",
"8"
]
}
创建容器
# 删除所有容器
[root@docker ~]# docker rm -f $(docker ps -aq)
......
# 删除所有镜像
[root@docker ~]# docker rmi $(docker images --format='{{.Repository}}:{{.Tag}}')
......
# 下载镜像
[root@docker ~]# docker pull registry:5000/img/mylinux:latest
2b7cd6d88a7665dbea0a4b3d99478e9f302c0a5661d7676d6d3bd3cb6d181
# 创建容器
[root@docker ~]# docker run -itd --rm registry:5000/library/myhttpd:latest
9e51547d5b7cc91229581560a7bee94c69f2ee07cf4114f4d8748b2c05e9c
# library 是默认路径,可以省略路径地址
[root@docker ~]# docker run -itd --rm myhttpd:latest
634766f788d665dbea0a4b39709e0a2cc8624fd99478e9f302c0a5661d767