Day02-容器管理案例与端口映射
-
- [1.7 Docker的容器管理](#1.7 Docker的容器管理)
-
- 1)案例08:查看当前运行中的容器,查看下80端口是否被占用,如果没有运行1个nginx容器使用80端口
- 2)案例09:创建centos容器并进入容器
- [3)案例10: 如何进入已经运行中的容器](#3)案例10: 如何进入已经运行中的容器)
- [4)案例11: exec vs attach区别](#4)案例11: exec vs attach区别)
- [5)案例12:docker run vs docker create,start,stop,restart](#5)案例12:docker run vs docker create,start,stop,restart)
- 6)案例13:我们传输文件到容器中,如何做?
- 7)案例14:查看容器信息与状态
- 8)案例15:结束容器
- 9)案例16:commit用于自定义镜像
- docker容器指令小结
- [1.8 端口映射(docker run -p)](#1.8 端口映射(docker run -p))
- [1.9 数据卷挂载](#1.9 数据卷挂载)
- 今日总结
9)jq
bash
# json形式数据:key value 键值对,变量和变量内容
# 这是1条harryYang
{
"name": "harryYang",
"age": 38,
"height": 100,
"weight": "100kg"
}
# 处理json形式数据的专用命令:jq.
# 案例01 - 处理简易格式的json数据
[root@docker01.oldboylinux.cn ~]# cat json01.txt |jq
{
"name": "harryYang",
"age": 38,
"height": 100,
"weight": "100kg"
}
[root@docker01.oldboylinux.cn ~]# cat json01.txt |jq .age
38
[root@docker01.oldboylinux.cn ~]# cat json01.txt |jq .name
"harryYang"
[root@docker01.oldboylinux.cn ~]# name=`cat json01.txt |jq .name`
[root@docker01.oldboylinux.cn ~]# echo $name
"harryYang"
# 案例02 处理复杂格式docker inspect
# 先去掉[]就可以过滤了.
docker inspect nginx:alpine | jq .[].Id
docker inspect nginx:alpine | jq .[].Created
docker inspect nginx:1.22-alpine | jq .[].Created
docker inspect nginx:1.22-alpine | jq .[]
docker inspect nginx:1.22-alpine | jq .[].ContainerConfig
docker inspect nginx:1.22-alpine | jq .[].ContainerConfig.Hostname
# 遇到花括号({})直接.遇到中括号([])就来个[]
说明:
["苹果","香蕉","橘子","西瓜","葡萄","榴莲"] 列表
说出你喜欢的水果
- 苹果
- 香蕉
- 橘子
- 西瓜
- 葡萄
- 榴莲
1.7 Docker的容器管理
- 运行起来的镜像可以称为容器,1个容器相当于是1个进程
bash
docker container xxx # 开头的指令一遍表示容器管理指令,部分指令container可以省略
bash
docker ps 查看容器列表 -a 查看所有容器
docker run 创建并运行容器
例子:docker run -d -it -p 80:80 nginx:latest
docker create 创建容器 Վʔname
docker start 启动容器
docker stop 停止容器
docker restart 重启容器
docker kill 强制停止容器
docker rm 删除容器
批量删除所有容器 docker rm -f `docker ps -a -q`
docker exec 进入正在运行的容器(分配一个新终端)
例子: docker exec -it 容器id/容器名字
/bin/bash(/bin/sh)
docker attach 进入正在运行的容器(使用相同的终端),偷偷离开
的快捷键ctrl +p,ctrl +q
inspect
stats
top
1)案例08:查看当前运行中的容器,查看下80端口是否被占用,如果没有运行1个nginx容器使用80端口
bash
docker container ps == docker ps
#01查看运行中的容器 docker ps
[root@docker01 ~]# docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#02查看所有状态的容器 docker ps -a #all
root@docker01 ~]# docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5fced2d10d86 nginx:alpine "/docker-entrypoint...." 22 hours ago Exited (255) 41 minutes ago 0.0.0.0:80->80/tcp, :::80->80/tcp oldboy_first_docker_nginx
- 删除容器
bash
docker container rm == docker rm
docker rm 容器
如果容器运行中无法删除则使用rm -f强制删除.
- 运行容器
bash
docker run -d -p 80:80 --name oldboy_nginx_alpine_v2 nginx:alpine
-
容器使用三部曲指令小结
-
docker container ps == docker ps 选项-a查看所有状态的容器,-q只输出容器的id号可以用于批量删除容器docker rm -f $(docker ps -q)
-
docker rm 删除容器,-f强制删除容器
-
docker run docker核心指令,选项也是最多
- -d 容器后台运行
- -p 端口映射,外部或其他服务器想要访问容器内部的某个服务的端口;-p外部用于访问的端口:容器内部服务的端口
- --name 指定容器的名字
-
2)案例09:创建centos容器并进入容器
- 温馨提示:并不是进入1个已经在运行中的容器
bash
docker run -it --name "oldboy_centos_v1" centos
[root@4dba12df1a46 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 02:16 pts/0 00:00:00 /bin/bash
root 15 1 0 02:16 pts/0 00:00:00 ps -ef
- 如果退出容器,那么容器状态会怎么样?
-it 运行容器,容器是一个系统.
容器退出后,容器关闭了
- 关于docker run -it说明
-i 进入交互模式
-t 分配一个终端(运行命令解释器) /bin/bash 或 /bin/sh
-it 进入容器并有个命令行(终端)
好处:运行容器的同时可以进入到容器中;缺点:退出容器则容器结束。
- 体会下面2个命令的区别:
bash
docker run -d --name "oldboy_centos_v2" centos
docker run -d --name "oldboy_centos_v3" centos sleep 20
温馨提示::
容器想要放在后台(-d)一直运行的话,那么容器运行对应初始命令,
必须夯住(阻塞/前台运行),否则容器就会退出
bash前台运行 nginx -g 'daemon off;' nginx前台运行. /usr/sbin/php-fpm --nodaemonize php前台运行. /usr/sbin/sshd -D ssh前台运行. java -jar xxx.jar java前台运行.
3)案例10: 如何进入已经运行中的容器
bash
#0. 如果没有运行中的容器创建1个.
docker run -d -p 80:80 --name "oldboy_nginx_alpine_v2" nginx:alpine
#1. 进入运行中的容器中
[root@docker01 ~]# docker exec -it oldboy_nginx_alpine_v2 /bin/bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
[root@docker01 ~]# docker exec -it oldboy_nginx_alpine_v2 /bin/sh
#2. 修改ngx首页文件内容
echo oldboy_docker_nginx_alpine_v2 >/usr/share/nginx/html/index.html
#3. 浏览器测试
- 小扩展:如何后台持续运行纯净系统的容器
bash
#通过-itd + 指定命令解释器持续运行
docker run -itd --name oldboy_centos_v6 centos /bin/bash
#如果连接exec
- docker exec小结
- 用于与已经运行中的容器进行连接
- -it 交互模式分配终端
- docker exec -it --name xxx 镜像名字:版本 参数(一般/bin/bash 或/bin/sh)
- nginx -t;nginx -s reload
4)案例11: exec vs attach区别
docker container 指令 | exec | attach |
---|---|---|
共同点 | 连接到容器 | 连接到容器 |
区别 | 连接的时候创建终端 | 容器要有终端(容器进程中要有个/bin/bash 或/bin/sh) 只能连接到已有的终端中 |
区别 | 不同的exec连接互不影响 | 共用,所有连接都一样 |
bash
[root@docker01 ~]# docker run -itd --name nginx_attach_test_v1 nginx /bin/bash
86d7b7c1d8bc105632588823892bcf1309ec658e9c5a074e0fc8af8cf585b7f6
[root@docker01 ~]# docker attach nginx_attach_test_v1
root@86d7b7c1d8bc:/#
5)案例12:docker run vs docker create,start,stop,restart
- docker run背后
- docker pull #如果镜像不存在
- docker create 创建容器
- docker start 启动容器
- docker stop 关闭容器, #向容器中的主进程,pid 1 进程发出信号(kill),关闭。
- docker restart重启重启
6)案例13:我们传输文件到容器中,如何做?
- 之前我们在windows与linux之间通过lrzsz实现.
- docker container cp == docker cp
源 | 目标 | ||
---|---|---|---|
宿主机-->容器 上传 | docker cp | 路径或文件 | 容器:容器中目录 |
容器-->宿主机 下载 | docker cp | 容器:容器中目录 | 路径或文件 |
bash
#1. 保存百度首页文件
curl -o index.html www.baidu.com
#2. 上传首页文件到nginx容器中.
[root@docker01 ~]# docker cp index.html oldboy_nginx_alpine_v2:/usr/share/nginx/html/index.html
Successfully copied 4.1kB to oldboy_nginx_alpine_v2:/usr/share/nginx/html/index.html
#3. 检查效果
- docker cp:
- 宿主机与容器间互传数据
- -a表示保存文件属性不变(uid,gid)
7)案例14:查看容器信息与状态
- stats 查看所有运行中的容器的状态,如果要看所有加上-a选项
bash
docker container stats == docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
29c28f62864b oldboy_nginx_debian_v1 0.00% 3.07MiB / 3.839GiB 0.08% 722B / 656B 0B / 0B 5
3bd0dfbaaecf oldboy_nginx_alpine_v3 0.00% 2.938MiB / 3.839GiB 0.07% 3.41kB / 656B 0B / 7.68kB 5
fb851450a2f6 oldboy_nginx_alpine_v2 0.00% 4.848MiB / 3.839GiB 0.12% 11.6kB / 12.5kB 6.34MB / 11.8kB 5
- top 查看某一个容器的进程信息
bash
[root@docker01 ~]# docker top oldboy_nginx_debian_v1
UID PID PPID C STIME TTY TIME CMD
root 7357 7336 0 12:34 ? 00:00:00 nginx: master process nginx -g daemon off;
101 7394 7357 0 12:34 ? 00:00:00 nginx: worker process
101 7395 7357 0 12:34 ? 00:00:00 nginx: worker process
101 7396 7357 0 12:34 ? 00:00:00 nginx: worker process
101 7397 7357 0 12:34 ? 00:00:00 nginx: worker process
- inspect
bash
[root@docker01 ~]# docker inspect oldboy_centos_v1 |jq .[].Name
"/oldboy_centos_v1"
8)案例15:结束容器
- docker stop 关闭容器
- docker rm 删除容器
- docker kill
bash
docker kill -s 9 oldboy_nginx_alpine_v4
-s表示信号 -s 9 等于 kill -9 pid强制结束
9)案例16:commit用于自定义镜像
- 处理容器,生成镜像
- 使用流程:
- 运行服务镜像或系统镜像,启动后成为容器
- 根据我们的需求,对容器进行修改
- 测试完成后
- 最后通过commit命令把容器保存为镜像
- 根据新生成的镜像创建容器并测试
容器需求 |
---|
基于ngx镜像创建容器 |
修改站点目录 /app/code/restart/ (default.conf) |
上传代码,解压 |
测试 |
commit |
- 创建容器
bash
docker run -d -p 80:80 --name "oldboy_ngx_restart_alpine_v1" nginx:alpine
- 进入容器
bash
docker exec -it oldboy_ngx_restart_alpine_v1 /bin/sh
- 修改配置文件与准备环境
bash
/ # cat /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name restart.oldboylinux.cn;
root /app/code/restart;
location / {
index index.html;
}
location ~* \.css$ {
root /app/code/restart/css;
# alias /css/;
#docker.oldboylinux.cn/lidao.css
#docker.oldboylinux.cn/css/lidao.css;
}
}
- 上传代码,解压与测试
bash
docker cp restart-new.zip oldboy_ngx_restart_alpine_v1:/app/code/restart/
- 根据容器生成镜像
bash
docker commit oldboy_ngx_restart_alpine_v1 nginx:alpine_restart_v1
[root@docker01.oldboylinux.cn ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx alpine_restart_v1 58b01dc67e4c 15 seconds ago 30.2MB
nginx 1.22 8c9eabeac475 4 days ago 142MB
nginx 1.22-alpine 652309d09131 3 weeks ago 23.5MB
nginx 1.22-alpine-lidao996 652309d09131 3 weeks ago 23.5MB
nginx 1.22-alpine-oldboy 652309d09131 3 weeks ago 23.5MB
nginx alpine cc44224bfe20 14 months ago 23.5MB
nginx latest 605c77e624dd 14 months ago 141MB
centos latest 5d0da3dc9764 17 months ago 231MB
- 根据新生成的镜像创建容器 81端口
bash
docker run -d -p 81:80 --name "oldboy_ngx_restart_v2" nginx:alpine_restart_v1
-
浏览器访问测试
-
手动自定义镜像全流程
docker容器指令小结
- docker run
- docker ps
- docker rm
- docker cp
- docker exec vs attach
- docker stats,top,inspect
- docker commit 自定义镜像
1.8 端口映射(docker run -p)
-
使用docker的时候 外界访问docker容器中的服务或端口,需要使用端口映射,本质类似于iptables防火墙的端口映射
docker无视防火墙firewalld的原因:其实docker并不是绕过了防火墙,只是因为它往iptables里写了规则。
你在firewalld里看不到而已。(centos7系统既有iptables,也有firewalld)
在docker安装完后,会接管iptables,只要你docker run的时候加入参数,他会自动向iptables里面添加规则。
所以使用 -p 容器端口:主机端口,最终会在iptables中添加上容器的端口。
-
应用场景:未来容器需要被外界访问(80端口),需要暴漏在外界一个端口。
-
用户通过端口访问容器中的某个端口。
-
实现方法:docker run通过-p选项实现。
-
本质是通过iptables nat规则实现的.nat表中创建了docker自定义的链
2)用户访问的时候经历了什么?
3)端口映射案例
a)1对1端口映射
docker run | |
---|---|
-p选项(小写字母P) 宿主机端口:容器中的端口 | -p 80:80 -p 443:443 |
-p :容器中端口 | -p :80 表示宿主机端口随机,很少用. |
-p 端口范围:端口范围 | 80-88:80-88 |
bash
docker run -d --name "oldboy_nginx_80" -p 80:80 nginx:1.20.2-alpine
b)映射多个端口
- 映射8080,8081,8082 到容器中容器中也是8080,8081,8082
bash
一个一个写
docker run -d -p 8080:8080 -p 8081:8081 -p 8082:8082 -p 86:80 nginx:1.20.2-alpine
docker port hopeful_northcutt(容器名字或id)
表示连续
docker run -d -p 8084-8086:8080-8082 -p 88:80 nginx:1.20.2-alpine
c)ip绑定端口
-
显示用户只能通过宿主机的某个网卡连接这个端口
-
安全防护作用
bash
[root@docker01 ~]# docker run -d -p 80:80 nginx:alpine
ed338e616a1400223ac6c48ca3b6ff6546a74c3eadad38849fcaf2c4f1f454b1
[root@docker01 ~]# ss -lntup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 16384 *:80 *:* users:(("docker-proxy",pid=15300,fd=4))
tcp LISTEN 0 128 *:22 *:* users:(("sshd",pid=1151,fd=3))
tcp LISTEN 0 16384 [::]:80 [::]:* users:(("docker-proxy",pid=15306,fd=4))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1151,fd=4))
[root@docker01 ~]# docker run -d -p 172.16.1.81:81:80 nginx:alpine
fce93d381abc1dd565edea12bca2c5db1c7886e100f92fe8f880ab091f011db7
[root@docker01 ~]# ss -lntup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 16384 *:80 *:* users:(("docker-proxy",pid=15300,fd=4))
tcp LISTEN 0 16384 172.16.1.81:81 *:* users:(("docker-proxy",pid=15455,fd=4))
tcp LISTEN 0 128 *:22 *:* users:(("sshd",pid=1151,fd=3))
tcp LISTEN 0 16384 [::]:80 [::]:* users:(("docker-proxy",pid=15306,fd=4))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1151,fd=4))
4)小结
- 熟练掌握通过-p选项配置端口映射,映射1个或多个端口即可
- 掌握用户访问与docker
- 了解:-p背后做了什么
1.9 数据卷挂载
1)概述
-
这里我们想个问题,创建了一个容器,容器里面存放很多代码,数据,软件包等等信息,不小心删除容器 rm -f
-
重新创建名字相同的容器,问数据还有没有?
-
如何解决数据持久化问题?数据卷(挂载),让数据永久保存在宿主机中
2)实战
- 不使用数据卷,数据会丢失
- 数据卷使用 -v选项
docker run | |
---|---|
-v | 指定要挂载的目录/文件 |
-v 宿主机的路径:容器内部路径 |
- 挂载文件 宿主机的/app/docker/code/index.html 挂载到容器/usr/share/nginx/html/index.html
bash
mkdir -p /app/docker/{conf,code}
echo docker.oldboylinux.cn data volumne >/app/docker/code/index.html
- 挂载文件
bash
[root@docker01 code]# docker run -d --name "docker_volumnt_ngx_v1" -p 80:80 -v /app/docker/code/index.html:/usr/share/nginx/html/index.html nginx:alpine
注意:使用vi/vim/sed -i修改,需要重启下容器,因为对应文件inode变化,导致容器无法识别
- 查看容器挂载的数据卷
bash
[root@docker01 code]# docker inspect docker_volumnt_ngx_v1 |jq .[].HostConfig.Binds
[
"/app/docker/code/index.html:/usr/share/nginx/html/index.html"
]
今日总结
-
Docker 镜像
- docker pull
- docker images
- docker rmi
- dokcer inspect
- docker save/load
-
Docker容器指令
- docker run
- docker rm
- docker ps/stats/top/inspect
- docker commit
-
Docker端口映射-p选项
-
Docker数据卷 -v
- 挂载1个文件
- 挂载目录