购买云服务器
docker-0003 192.168.1.33 2cpu 4Gi
容器的安装部署
[root@docker ~]# echo 'net.ipv4.ip_forward = 1' >>/etc/sysctl.conf[root@docker ~]# sysctl -p
[root@docker ~]# dnf install -y docker-ce
[root@docker ~]# systemctl enable --now docker
# 查看服务器与客户端版本
[root@docker ~]# docker version
Client: Docker Engine - Community
Version: 20.10.10
... ...
Server: Docker Engine - Community
Engine:
Version: 20.10.10
添加镜像加速
[root@docker ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://registry:5000","https://5b2b824675ad46eeb14b2a305fcf560e.mirror.swr.myhuaweicloud.com“],
"insecure-registries":["http://registry:5000"]
}
[root@docker ~]# systemctl restart docker
镜像管理命令
镜像管理命令 说明
docker images 查看本机镜像
docker pull 镜像名称:标签 下载镜像
docker save 镜像名称:标签 -o 文件名 备份镜像为tar包
docker load -i 备份文件名称 导入备份的镜像文件
docker history 镜像名称:标签 查看镜像的制作历史
镜像查看
[root@docker-0003 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myos php-fpm f70bdfd2042c 9 months ago 275MB
myos nginx 10dc658da2fe 9 months ago 274MB
myos latest 1de38c85c2d1 10 months ago 4.67MB
myos httpd 9245e660f88f 10 months ago 299MB
myos 8.5 621bfd7f9b46 10 months ago 249MB
rockylinux 8.5 210996f98b85 23 months ago 205MB
busybox latest a9d583973f65 2 years ago 1.23MB
镜像备份、导入
[root@docker ~]# docker load -i myos.tar.xz
Loaded image: rockylinux:8.5
Loaded image: myos:8.5
Loaded image: myos:php-fpm
Loaded image: myos:nginx
Loaded image: myos:httpd
Loaded image: myos:latest
[root@docker ~]# docker save busybox:latest -o busybox.tar
容器管理命令
容器管理命令 说明
docker run -it(d) 镜像名称:标签 创建容器
docker ps 查看容器的信息
docker inspect 镜像名称|容器名称 查询(容器/镜像)的详细信息
docker [start|stop|restart] 容器id 启动、停止、重启容器
docker exec -it 容器ID 启动命令 在容器内执行命令
docker cp 路径1 路径2 拷贝文件:路径格式(本机路径、容器ID/路径)
创建容器
[root@docker-0003 ~]# docker run -it myos:8.5
[root@93cebec6e38e /]#
[root@93cebec6e38e /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
[root@93cebec6e38e /]#
创建一个web1的容器在后台运行
[root@docker-0003 ~]# docker run -itd --name web1 myos:httpd
5a504cb14dd78a1303f307b3258940b57f67bd3b1bfb53560958497a32db0e51
[root@docker-0003 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a504cb14dd7 myos:httpd "httpd -DFOREGROUND" 6 seconds ago Up 5 seconds 80/tcp web1
[root@docker-0003 ~]#
查询容器的状态
[root@docker-0003 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a504cb14dd7 myos:httpd "httpd -DFOREGROUND" About a minute ago Up About a minute 80/tcp web1
93cebec6e38e myos:8.5 "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago focused_mayer
[root@docker-0003 ~]# docker ps -aq #查看容器id
5a504cb14dd7
93cebec6e38e
容器开始、停止、重启
[root@docker-0003 ~]# docker stop web1
web1
[root@docker-0003 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a504cb14dd7 myos:httpd "httpd -DFOREGROUND" 3 minutes ago Exited (0) 7 seconds ago web1
[root@docker-0003 ~]# docker start web1
web1
[root@docker-0003 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a504cb14dd7 myos:httpd "httpd -DFOREGROUND" 5 minutes ago Up 3 seconds 80/tcp web1[root@docker-0003 ~]# docker restart web1
web1
[root@docker-0003 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a504cb14dd7 myos:httpd "httpd -DFOREGROUND" 5 minutes ago Up 5 seconds 80/tcp web1
容器内执行命令
# 在容器内执行非交互命令
[root@docker-0003 ~]# docker exec -it web1 /bin/ls
index.html info.php
# 在容器内执行交互式命令
[root@docker-0003 ~]# docker exec -it web1 /bin/ls
index.html info.php
[root@docker-0003 ~]# docker exec -it web1 /bin/bash
[root@5a504cb14dd7 html]# ls /root
[root@5a504cb14dd7 html]# id
uid=0(root) gid=0(root) groups=0(root)
# 从容器内拷贝文件出来
[root@docker-0003 ~]# docker cp web1:/etc/httpd/conf/httpd.conf ./
[root@docker-0003 ~]# ls
busybox.tar httpd.conf myos.tar.xz
# 把文件拷进容器内
[root@docker-0003 ~]# sed -ri 's,Listen 80,Listen 8080,' httpd.conf #把文件Listen 80这一行替换为 Listen 8080
[root@docker-0003 ~]# docker cp httpd.conf web1:/etc/httpd/conf/httpd.conf
容器技术
镜像编排
Dockerfile详解
指令 说明
FROM 指定基础镜像(唯一)
RUN 在容器内执行命令,可以写多条
ADD 把文件拷贝的容器内,如果文件是 tar.xx 格式,会自动解压
COPY 把文件拷贝的容器内,不会自动解压
ENV 设置启动容器的环境变量
WORKDIR 设置启动容器的默认工作目录(唯一)
CMD 容器默认的启动参数(唯一)
ENTRYPOINT 容器默认的启动命令(唯一)
USER 启动容器使用的用户(唯一)
EXPOSE 使用镜像创建的容器默认监听使用的端口号/协议
# 编写 Dockerfile
apache 镜像
拷贝php测试文件到 /root/ 目录下
rsync -av public/info.php 192.168.1.32:/root/
准备配置文件

[root@docker ~]# mkdir httpd
# 设置测试页面
[root@docker ~]# echo 'Welcome to The Apache.' >httpd/index.html
[root@docker ~]# cp -a info.php httpd/
[root@docker ~]# tar czf httpd/myweb.tar.gz -C httpd index.html info.php
# 获取配置文件
[root@docker ~]# docker run -itd --name myweb mylinux:latest
[root@docker ~]# docker exec -it myweb dnf install -y httpd
[root@docker ~]# docker cp myweb:/etc/httpd/conf.modules.d/00-mpm.conf httpd/
[root@docker ~]# docker rm -f myweb
# 修改配置文件
[root@docker ~]# sed -ri -e 's,^Load.*,#&,' -e 's,^#(.*mod_mpm_prefork.so)$,\1,' httpd/00-mpm.conf
制作镜像

# 编写 dockerfile 文件
[root@docker ~]# vim httpd/Dockerfile
FROM mylinux:latest
RUN dnf install -y httpd php && dnf clean all
ADD myweb.tar.gz /var/www/html/
COPY 00-mpm.conf /etc/httpd/conf.modules.d/
ENV LANG=C
WORKDIR /var/www/html/
EXPOSE 80/tcp
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
[root@docker ~]# docker build -t httpd:latest httpd
......
Successfully tagged httpd:latest
验证镜像

# 查看镜像并创建容器
[root@docker ~]# docker images httpd:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest c1e854cde1f4 About a minute ago 299MB
[root@docker ~]# docker run -itd --name myweb httpd:latest
cc2b82ad0367172c344c7207def94c4c438027c60859e94883e440b53a860a93
# 查看容器地址并访问验证
[root@docker ~]# docker inspect myweb |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 myweb
nginx 镜像
拷贝 public/nginx-1.22.1.tar.gz 到 docker 主机
rsync -av public/nginx-1.22.1.tar.gz 192.168.1.32:./
编译软件包

# 安装编译工具和依赖软件包
[root@docker ~]# dnf install -y openssl-devel pcre-devel gcc make
# 编译安装
[root@docker ~]# tar zxf nginx-1.22.1.tar.gz
[root@docker ~]# cd nginx-1.22.1/
[root@docker nginx-1.22.1]# ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module
[root@docker nginx-1.22.1]# make && make install
# 设置默认首页
[root@docker nginx-1.22.1]# echo 'Nginx is running !' >/usr/local/nginx/html/index.html
制作镜像

[root@docker ~]# mkdir nginx
# 将编译好的 nginx 打包,这里必须使用相对路径
[root@docker ~]# tar czf nginx/nginx.tar.gz -C /usr/local nginx
[root@docker ~]# vim nginx/Dockerfile
FROM mylinux:latest
RUN dnf install -y pcre openssl && dnf clean all
ADD nginx.tar.gz /usr/local/
ENV PATH=${PATH}:/usr/local/nginx/sbin
WORKDIR /usr/local/nginx/html
EXPOSE 80/tcp
CMD ["nginx", "-g", "daemon off;"]
[root@docker ~]# docker build -t nginx:latest nginx
Successfully tagged nginx:latest
验证镜像

# 查看镜像并创建容器
[root@docker ~]# docker images nginx:latest
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 645dd2d9a8ec 3 minutes ago 274MB
[root@docker ~]# docker run -itd --name myweb nginx:latest
e440b53a860a93cc2b82ad0367172c344c7207def94c4c438027c60859e94883
# 查看容器地址并访问验证
[root@docker ~]# docker inspect myweb |grep -i IPAddress
[root@docker ~]# curl http://172.17.0.2/
Nginx is running !
# 查看 nginx 服务的用户
[root@docker ~]# docker exec -it myweb ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 15:48 pts/0 00:00:00 nginx: master process nginx
nobody 7 1 0 15:48 pts/0 00:00:00 nginx: worker process
root 32 0 0 15:49 pts/1 00:00:00 ps -ef
[root@docker ~]# docker rm -f myweb
制作php-fpm镜像
#手工部署创建所需的php配置文件
[root@docker-0003 ~]# docker run -it --name myphp myos:8.5
[root@f6c3fc8eea1b /]# yum install -y php-fpm
[root@f6c3fc8eea1b /]# vim /etc/php-fpm.d/www.conf #修改配置文件
38: listen = 127.0.0.1:9000
[root@f6c3fc8eea1b /]exit
[root@docker-0003 ~]# docker cp myphp:/etc/php-fpm.d/www.conf ./
[root@docker-0003 ~]# mkdir php
[root@docker-0003 ~]# cp www.conf php/
[root@docker-0003 ~]# cd php
[root@docker-0003 php]# vim Dockerfile
FROM myos:8.5
RUN yum -y install php-fpm && yum clean all && \
mkdir -p /run/php-fpm && \
chown -R nobody:nobody /run/php-fpm /var/log/php-fpm
COPY www.conf /etc/php-fpm.d/www.conf
USER nobody
EXPOSE 9000/tcp
CMD ["/usr/sbin/php-fpm","--nodaemonize"]
~
[root@docker-0003 php]# docker build -t php-fpm:latest ./
[root@docker-0003 php]# docker run -itd --name myphp php-fpm:latest
[root@docker-0003 php]# docker exec -it myphp /bin/bash
bash-4.4$ id
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)
bash-4.4$ ps -ef
UID PID PPID C STIME TTY TIME CMD
nobody 1 0 0 12:06 pts/0 00:00:00 php-fpm: master process (/etc/php-fpm.conf)
nobody 7 1 0 12:06 pts/0 00:00:00 php-fpm: pool www
nobody 8 1 0 12:06 pts/0 00:00:00 php-fpm: pool www
nobody 9 1 0 12:06 pts/0 00:00:00 php-fpm: pool www
nobody 10 1 0 12:06 pts/0 00:00:00 php-fpm: pool www
nobody 11 1 0 12:06 pts/0 00:00:00 php-fpm: pool www
nobody 12 0 0 12:06 pts/1 00:00:00 /bin/bash
nobody 19 12 0 12:06 pts/1 00:00:00 ps -ef
bash-4.4$ exit
exit
[root@docker-0003 php]# docker rm -f myphp
docker 私有仓库
主机清单
主机名 ip地址 最低配置
registry 192.168.1.34 2CPU,4G内存
registry 安装
# 在 registry 上安装私有仓库
[root@registry ~]# dnf install -y docker-distribution
# 启动私有仓库,并设置开机自启动
[root@registry ~]# systemctl enable --now docker-distribution
客户端配置
所有 node 节点都需要配置
[root@docker ~]# vim /etc/hosts
192.168.1.35 registry
# 修改配置文件
[root@docker ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://registry:5000"],
"insecure-registries":["registry:5000"]
}
# 重启服务生效
[root@docker ~]# systemctl restart docker
上传镜像
# 给 nginx 镜像设置标签
[root@docker ~]# docker tag nginx:latest registry:5000/img/myimg:web
# 上传 nginx 镜像
[root@docker ~]# docker push registry:5000/img/myimg:web
The push refers to repository [registry:5000/img/myimg]
c9d01852a13b: Pushed
......
web: digest: sha256:3e1fc9ad1ee46ee4619c95dc9d71034d919e53abfc size: 952
# 上传 php-fpm 镜像
[root@docker ~]# docker tag php-fpm:latest registry:5000/img/myimg:php-fpm
[root@docker ~]# docker push registry:5000/img/myimg:php-fpm
The push refers to repository [registry:5000/img/myimg]
619c95dc93e1: Pushed
......
php-fpm: digest: sha256:619c95dc93e1fc9ad1ee46ee4d71034d919e53abfc size: 875
# 上传 httpd 镜像
[root@docker ~]# docker tag httpd:latest registry:5000/library/httpd:latest
[root@docker ~]# docker push registry:5000/library/httpd:latest
The push refers to repository [registry:5000/library/httpd]
95dc9d71034d: Pushed
......
latest: digest: sha256:95dc9d71034d919e53abfc3e1fc9ad1ee46ee4619c size: 968
验证测试
查看镜像名称: 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/myimg", "library/httpd"]}
# 查看某一镜像的所有标签
[root@docker ~]# curl http://registry:5000/v2/img/myimg/tags/list
{"name":"img/myimg","tags":["web", "php-fpm"]}
# 易读格式查看镜像名称
[root@docker ~]# curl -s http://registry:5000/v2/_catalog |python3 -m json.tool
{
"repositories": [
"img/myimg",
"library/httpd"
]
}
# 易读格式查看镜像标签
[root@docker ~]# curl -s http://registry:5000/v2/img/myimg/tags/list |python3 -m json.tool
{
"name": "img/myimg",
"tags": [
"php-fpm",
"web"
]
}
创建容器
# 删除所有容器
[root@docker ~]# docker rm -f $(docker ps -aq)
......
# 删除所有镜像
[root@docker ~]# docker rmi $(docker images -q)
......
# 使用仓库中的镜像运行容器
[root@docker ~]# docker run -itd --rm registry:5000/img/myimg:web
2b7cd6d88a7665dbea0a4b3d99478e9f302c0a5661d7676d6d3bd3cb6d181
# library 是默认路径,可以省略路径地址
[root@docker ~]# docker run -itd --rm httpd:latest
634766f788d665dbea0a4b39709e0a2cc8624fd99478e9f302c0a5661d767
容器对外发布服务
[root@docker-lhh ~]# docker run -itd --name web -p 80:80 myos:httpd
84896e188d1ae5ef199af4485dccb2a44843056b86d35997109a9d8c1b8b0f0b
[root@docker-lhh ~]# curl 192.168.1.30
Welcome to The Apache.
[root@docker-lhh ~]# docker rm -f web
web
[root@docker-lhh ~]# docker run -itd --name web -p 80:80 myos:nginx
1603a4a7cc7ffd771791ac9af60392ab43939e41994fca825ddb748646323079
[root@docker-lhh ~]# curl 192.168.1.30
Nginx is running !
[root@docker-lhh ~]# docker rm -f web
web
[root@docker-lhh ~]#
容器对外发布服务解决了容器重启之后随机IP的问题,客户只需访问宿主机的IP地址。
容器卷概述
容器化带来的问题
1.重要数据在容器内不方便管理易丢失
2. 修改多个容器中的数据非常困难
3. 多个容器之间的数据有数据共享、同步需求
4. 数据文件与配置文件需要频繁更改
修改配置文件
# 获取配置文件
[root@docker ~]# mkdir /var/webconf
[root@docker ~]# docker cp mynginx:/usr/local/nginx/conf/nginx.conf /var/webconf/
# 编辑配置文件,添加 php 解析配置
[root@docker ~]# vim /var/webconf/nginx.conf
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
# 使用卷映射配置文件,重建 nginx 容器
[root@docker ~]# docker rm -f mynginx
[root@docker ~]# docker run -itd --rm --name mynginx -p 80:80 \
-v /var/webconf/nginx.conf:/usr/local/nginx/conf/nginx.conf \
-v /var/webroot:/usr/local/nginx/html myos:nginx
# 进入容器验证配置文件
[root@docker ~]# docker exec -it mynginx /bin/bash
[root@e440b53a860a html]# cat /usr/local/nginx/conf/nginx.conf
[root@docker ~]# docker run -itd --network=container:mynginx \
-v /var/webroot:/usr/local/nginx/html \
--rm --name myphp myos:php-fpm
# 配置验证
[root@docker ~]# docker exec -it mynginx ss -ltun
Netid State Recv-Q Send-Q Local Address:Port
tcp LISTEN 0 128 127.0.0.1:9000
tcp LISTEN 0 128 *:80
[root@docker ~]# curl http://127.0.0.1/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: 4525e99cea77
1229
服务编排与治理
容器服务治理
安装 compose 组件
[root@docker ~]# dnf install -y docker-compose-plugin
# 创建项目
[root@docker ~]# vim docker-compose.yaml
name: websvc
version: "3"
services:
websvc:
container_name: nginx
image: myos:nginx
容器项目管理

# 创建项目,并启动
[root@docker ~]# docker compose -f docker-compose.yaml up -d
[+] Running 2/2
⠿ Network websvc_default Created 0.0s
⠿ Container nginx Started 0.3s
# 查看项目
[root@docker ~]# docker compose ls
NAME STATUS CONFIG FILES
websvc running(1) /root/docker-compose.yaml
# 查看项目中的容器状态
[root@docker ~]# docker compose -p websvc ps
NAME COMMAND SERVICE STATUS PORTS
nginx "nginx -g 'daemon of…" websvc running 80/tcp
# 启动、停止、重启项目
[root@docker ~]# docker compose -p websvc stop
[+] Running 1/1
⠿ Container nginx Stopped 0.1s
[root@docker ~]# docker compose -p websvc start
[+] Running 1/1
⠿ Container nginx Started 0.2s
[root@docker ~]# docker compose -p websvc restart
[+] Running 1/1
⠿ Container nginx Started 0.3s
# 查看项目中容器的日志
[root@docker ~]# docker inspect nginx |grep IPAddress
[root@docker ~]# curl http://172.17.0.2/info.php
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>
[root@docker ~]# docker compose -p websvc logs
nginx | 2023/02/13 13:55:39 [error] 7#0: *1 open() "/usr/local/nginx/html/info.php" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /info.php HTTP/1.1", host: "172.17.0.2"
# 删除项目
[root@docker ~]# docker compose -p websvc down
[+] Running 2/2
⠿ Container nginx Removed 0.1s
⠿ Network websvc_default Removed 0.0s
指令 说明
up 创建项目并启动容器
down 删除项目容器及网络
ls 列出可以管理的项目
start/stop/restart 启动项目/停止项目/重启项目
images 列出项目使用的镜像
ps 显示项目中容器的状态
logs 查看下项目中容器的日志
compose 语法
指令
容器服务编排

[root@docker ~]# vim docker-compose.yaml
name: websvc
version: "3"
services:
nginxsvc:
container_name: nginx
image: myos:nginx
restart: always
volumes:
- type: bind
source: /var/webconf/nginx.conf
target: /usr/local/nginx/conf/nginx.conf
- type: bind
source: /var/webroot
target: /usr/local/nginx/html
network_mode: bridge
ports:
- 80:80
environment:
- "TZ=Asia/Shanghai"
php-fpm:
container_name: php-fpm
image: myos:php-fpm
restart: always
volumes:
- type: bind
source: /var/webroot
target: /usr/local/nginx/html
depends_on:
- nginxsvc
network_mode: "container:nginx"
验证项目

# 创建,并启动项目
[root@docker ~]# docker compose -f docker-compose.yaml up -d
[+] Running 2/2
⠿ Container nginx Started 0.3s
⠿ Container php-fpm Started 0.3s
# 查看项目
[root@docker ~]# docker compose ls
NAME STATUS CONFIG FILES
websvc running(2) /root/docker-compose.yaml
# 查看容器状态,验证服务
[root@docker ~]# docker compose -p websvc ps
NAME COMMAND SERVICE STATUS
nginx "nginx -g 'daemon of..." nginx running ......
php-fpm "php-fpm --nodaemoni..." php-fpm running ......
# 访问 php 页面验证
[root@docker ~]# curl -s http://127.0.0.1/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: 7e037978c775
1229
说明
networks 配置容器连接的网络
container_name 指定容器名称
depends_on 解决容器的依赖、启动先后的问题
command 覆盖容器启动后默认执行的命令
environment 设置环境变量
image 指定为镜像名称或镜像 ID
network_mode 设置网络模式
restart 容器保护策略[always、no、on-failure]
ports 暴露端口信息
volumes 数据卷,支持 [volume、bind、tmpfs、npipe]