wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/rbac.yaml
kubectl apply -f rbac.yaml
sotrageclass.yaml:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
archiveOnDelete: "false"
reclaimPolicy: Delete
该provisioner将会自动创建pv,以 −namespace−{pvcName}-${pvName} 的命名格式创建在 NFS 服务器的 /mnt/storage 目录上。
nfs-provisioner-deploy.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-provisioner
labels:
app: nfs-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-provisioner
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccountName: nfs-provisioner
containers:
- name: nfs-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
volumeMounts:
- name: nfs-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: fuseim.pri/ifs
- name: NFS_SERVER
value: 10.1.36.89
- name: NFS_PATH
value: /mnt/storage
volumes:
- name: nfs-root
nfs:
server: 10.1.36.89
path: /mnt/storage
nfs-statefulset.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nfs-web
spec:
serviceName: "nginx"
replicas: 3
selector:
matchLabels:
app: nfs-web # has to match .spec.template.metadata.labels
template:
metadata:
labels:
app: nfs-web
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
annotations:
volume.beta.kubernetes.io/storage-class: nfs-storage
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
启动后,发现创建的PVC状态一直处于pending状态。
排查步骤:
利用以上信息,找到相关线索:
kubernetes版本在v1.20起,默认禁止使用SelfLinks。
想办法开启SelfLinks。这里提供三种思路
一般在 /etc/kubernetes 下,可以 find / -name kube-apiserver.yaml 全局搜索,添加如下内容,然后重启kube-apiserver服务即可
如果没有找到kube-apiserver.yaml文件,比如通过二进制部署的,可以全局搜索 kube-apiserver.service (一般在 /etc/systemd/system/kube-apiserver.service),添加如下内容即可。修改完记得systemctl daemon-reload一下,并重启kube-apiserver服务
如果是用rancher部署的,那么需要修改其cluster.yml文件如下,然后更新配置:./rke up
问题解决
四,阿里云部署
以上是基于本地部署的k8s进行的动态存储配置,如果是在阿里云上,可以参考:
https://help.aliyun.com/document_detail/204404.html#title-g3c-55i-xs6
众号:渗透师老A
专注分享渗透经验,干货技巧....
进入内网之后、是一种由点到线再到面的测试,先弄清楚当前机器的情况,如在域中角色、提供的服务等信息;
再以此为跳板收集其它机器的信息,当收集的信息足够多,拿下域控的可能型也就越高。
为了后续的提权等操作,首先要尽可能拿下当前机器的权限,所以对当前机器的信息收集也是必要的。
|查看系统配置信息
ssysteminfo 查看系统信息,但是内容太多在某些时刻无法通过菜刀等工具看到返回的结果
可以将内容输出到某个文件,也可以结合findstr 查询指定内容
如查询操作系统即软件的信息 systeminfo | findstr /B /C:"OS"
该指令输入的内容是比较多的,除了使用finder选择输出外,部分信息可以使用其它指令单独显示
比如echo %processor_architecture%查看系统架构,net statistics workstation查看系统启动时间
其中的补丁信息可以使用wmic qfe get caption,description,hotfixid,installedon获取
WMIC扩展WMI(Windows Management Instrumentation,Windows管理工具) ,提供了从命令行接口和批命令脚本执行系统管理的支持。
在cmd中有些时候查到的数据不全,如某些进程的pid,这时可以使用wmic进行操作,WMIC提供了大量的全局开关、别名、动词、命令和丰富的命令行帮助增强用户接口。
wmic product get name,version,查看系统安装的软件版本等内容。
wmic /node:localhost /namespace:\root\securitycenter2 path antivirusproduct get displayname /format:list查杀软
初次之外,还可以使用netsh firewall show config和netsh advfirewall firewall show config查看防火墙配置信息
|查看系统服务信息
wmic startup get command,caption,查看启动程序信息
wmic service list brief,查询本机服务信息
还可以使用tasklist 查询进程信息
schtasks /query /fo LIST /V,查看计划任务
netstat -ano查看端口列表
注意,一般查看进程端口,先查进程pid,在根据pid查端口
|查看系统登录信息
query user,登录到系统的用户信息
net session,列出连接会话信息,但是一般需要高权限才能执行
|自动信息收集
很多后渗透模块都可以进行信息收集,这里不谈,分享个嫖到的脚本
for /f "delims=" %%A in ('dir /s /b %WINDIR%\system32\*htable.xsl') do set "var=%%A"
wmic process get CSName,Description,ExecutablePath,ProcessId /format:"%var%" >> out.html
wmic service get Caption,Name,PathName,ServiceType,Started,StartMode,StartName /format:"%var%" >> out.html
wmic USERACCOUNT list full /format:"%var%" >> out.html
wmic group list full /format:"%var%" >> out.html
wmic nicconfig where IPEnabled='true' get Caption,DefaultIPGateway,Description,DHCPEnabled,DHCPServer,IPAddress,IPSubnet,MACAddress /format:"%var%" >> out.html
wmic volume get Label,DeviceID,DriveLetter,FileSystem,Capacity,FreeSpace /format:"%var%" >> out.html
wmic netuse list full /format:"%var%" >> out.html
wmic qfe get Caption,Description,HotFixID,InstalledOn /format:"%var%" >> out.html
wmic startup get Caption,Command,Location,User /format:"%var%" >> out.html
wmic PRODUCT get Description,InstallDate,InstallLocation,PackageCache,Vendor,Version /format:"%var%" >> out.html
wmic os get name,version,InstallDate,LastBootUpTime,LocalDateTime,Manufacturer,RegisteredUser,ServicePackMajorVersion,SystemDirectory /format:"%var%" >> out.html
wmic Timezone get DaylightName,Description,StandardName /format:"%var%" >> out.html
复制为bat文件,结果为out.html保存在c盘根目录,名称路径可自行修改。
|判断是否存在域
whoami,如果当前账户为域用户,则返回结果通常为域名\用户名
ipconfig,如果是双网卡,一般存在内网
systeminfo,如果在域中,则如图,否则为workgroup
net config workstation,在域中,通常计算机全名为计算机名.域名
不在域中如下图
net time /domain,查看时间服务器,域中机器的dns服务器和时间服务器通常为域控机。
如下图则是存在域且当前登录用户为域用户
如下图则表示不在域中
如下图则表示在域中,但当前用户非域用户
除此之外,收集其它内容的时候都能看到,比如系统信息,用户信息等
|探测域内存主机&端口
探测存活主机和端口平时最容易想到的工具是nmap,但这个工具太大,直接安装存在风险,端口转发受限于网络环境,这里聊聊其它方法
powershell
powershell可以在渗透中提供强大的助力,下面这些脚本使用的时候记得修改 ip地址
扫描存活ip,最前面的1..255是ip地址的d段,最后范围是192.168.0.1-255,判断和修改方式下同
1..255 | % {echo "192.168.0.$_"; ping -n 1 -w 100 192.168.0.$_} | Select-String ttl
判断主机类型,根据ttl值判断,范围192.168.0.1-255
1..255 | % {echo "192.168.0.$_"; ping -n 1 -w 100 192.168.0.$_} | Select-String ttl |% { if ($_ -match "ms") { $ttl = $_.line.split('=')[2] -as [int]; if ($ttl -lt 65) { $os = "linux"} elseif ($ttl -gt 64 -And $ttl -lt 129) { $os = "windows"} else {$os = "cisco"}; write-host "192.168.0.$_ OS:$os" ; echo "192.168.0.$_" >> scan_results.txt }}
扫描端口
24..25 | % {echo ((new-object Net.Sockets.TcpClient).Connect("192.168.1.119",$_)) "Port $_ is open!"} 2>$null
24..25 |% {echo "$_ is "; Test-NetConnection -Port $_ -InformationLevel "Quiet" 192.168.1.119}2>null
扫描指定端口的ip
foreach ($ip in 1..20) {Test-NetConnection -Port 80 -InformationLevel "Detailed" 192.168.0.$ip}
arp扫描
在内网里通常使用mac地址进行机器寻找,其可以通过arp协议实现
小工具
由很多免安装的小工具也可以进行扫描,比如nbtscan,直接传到目标服务器上运行即可,工具下载地址:http://www.unixwiz.net/tools/nbtscan.html
用法:nbtscan.exe 网段 ,更多用法参考:nbgtscam.exe /?
含义如下:
|Token|含义|
|——|——|
SHARING|机器正在运行的文件和打印共享服务,但这并不一定有内容共享
DC|机器可能是Windows NT域控制器,无论是主域还是辅助域。
U=user |机器可能有一个具有指定名称的登录用户
IIS |机器可能安装了Microsoft的Internet信息服务器(IIS)
EXCHANGE |机器可能安装Microsoft Exchange
NOTES |单机器可能安装Lotus Notes电子邮件客户端
? |没有识别出NETBIOS资源
telnet
telnet常规使用是和服务器建立连接,也开业用来探测端口是否开放
用法:telnet 主机 端口,如:telnet dc 3389。
注意:不是所有机器都安装了此服务。
|查看用户&机器&会话相关信息
查看机器相关信息
net view /domain,查询域信息,判断当前机器加入的域
net view /domain:域名,查询域内所有主机
在域中,有一类至关重要的机器叫域控制器,简称域控,机器名通常为DC,在实际环境中,域控为一主一备用两台。
netdom query pdc,查看域控名称
查看用户相关信息
net user查询当前机器所有用户,net user /domain查看域用户
net user 用户名查看当前机器内的用户信息
net user 用户名 /domain查看当前机器内的域用户信息
注意对比上述结果的区别,此外net user localgroup,net user localgroup /domain和net group /domain也是有区别的
wmic useraccount get /all,获取域内用户的详细信息
参考链接:
https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.3e221b11FUZo7g
系统环境:docker最低支持centos7且在64位平台上,内核版本在3.10以上。
可以通过命令 uname -a 查看版本情况,通过 cat /etc/issue 查看操作系统
[root@node6 ~]# uname -a
Linux node6 3.10.0-1062.4.1.el7.x86_64 #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[root@node6 ~]# cat /etc/issue
\S
Kernel \r on an \m
安装、运行、停止
# 安装docker
yum install -y docker 或者 yum install -y docker-io
# 启动docker
systemctl start docker
# 重启docker
systemctl restart docker
# 停止docker
systemctl stop docker
# 查看docker启动状态
docker version
如果安装完成后启动报如下错误:
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service"
按以下步骤解决:
第一步:yum remove docker-* 卸载docker。
第二步:yum update 更新linux系统内核的版本。
然后按照上面的安装步骤重新安装启动即可。
配置镜像加速器
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。找个国内可使用的镜像加速器地址,以centos为例来看怎们进行配置,镜像加速器可以配置多个:
#国内加速地址
#Docker中国区官方镜像
https://registry.docker-cn.com
#网易
http://hub-mirror.c.163.com
#ustc
https://docker.mirrors.ustc.edu.cn
#中国科技大学
https://docker.mirrors.ustc.edu.cn
#阿里云容器服务
https://cr.console.aliyun.com/
vi /etc/docker/daemon.json
然后编辑输入:
{
"registry-mirrors": [
"https://hub-mirror.c.163.com"
]
}
docker search hello-world # 搜索hello-world的镜像
docker pull hello-docker # 获取centos镜像
docker run hello-world #运行一个docker镜像,产生一个容器实例(也可以通过镜像id前三位运行)
docker image ls # 查看本地所有镜像
docker images # 查看docker镜像
docker image rmi hello-docker # 删除centos镜像
docker ps #列出正在运行的容器(如果创建容器中没有进程正在运行,容器就会立即停止)
docker ps -a # 列出所有运行过的容器记录
docker ps -l #查看最新创建的容器
docker ps -n=xxx #查看最新创建的n个容器
docker save centos > /opt/centos.tar.gz # 导出docker镜像至本地
docker load < /opt/centos.tar.gz #导入本地镜像到docker镜像库
docker stop `docker ps -aq` # 停止所有正在运行的容器
docker rm `docker ps -aq` # 一次性删除所有容器记录
docker rmi `docker images -aq` # 一次性删除所有本地的镜像记录
创建容器如下:
docker create nginx #创建一个nginx容器,这个时候创建的容器处于停止状态,未启动,这种创建方式容器名称随机生成,也可以自定义容器名称,如下:
docker create --name=nginx nginx
启动容器如下:
使用 `docker start` 命令结合容器 id 或者容器 name 可以启动一个容器。
一般来说,第一次可以使用 docker run 启动一个容器,以后直接使用 docker start 即可。
docker run --name nginx1 -d -p 8080:80 nginx
--name 表示创建的容器的名字,-d 表示容器在后台运行,-p 表示将容器的 80 端口映射到宿主机的 8080 端口。
docker run --name ubuntu -it ubuntu /bin/bash
参数含义和后台型容器描述一致,除了 -it,-it 参数,i 表示开发容器的标准输入(STDIN),t 则表示告诉docker,为容器创建一个命令行终端。
想要退出该终端,只需要输入 exit命令即可。
容器在运行过程中,会不可避免的出问题,出了问题时,需要能够自动重启,在容器启动时使用 –restart 参数可以实现这一需求。根据 docker 官网的解释,docker 的重启策略可以分为 4 种,如下图:
四种的含义分别如下:
no表示不自动重启容器,默认即此。
on:failure:[max-retries]表示在退出状态为非0时才会重启(非正常退出),有一个可选择参数:最大重启次数,可以设置最大重启次数,重启次数达到上限后就会放弃重启。
always表示始终重启容器,当docker守护进程启动时,也会无论容器当时的状态为何,都会尝试重启容器。
unless-stopped表示始终重启容器,但是当docker守护进程启动时,如果容器已经停止运行,则不会去重启它。
使用 `docker stop` 命令结合容器 id 或者容器 name 可以终止一个容器。
docker rm 命令结合容器 id 或者容器 name 可以删除一个容器。删除容器时,只能删除已经停止运行的容器,不能删除正在运行的容器。
如果非要删除一个正在运行的容器,可以通过 -f 参数实现,例如 docker rm -f nginx
容器也可以批量删除,命令如下:
docker rm $(docker ps -a -q)
docker ps -a -q 会列出所有容器的 id ,供 rm 命令删除。
如下命令也支持删除已退出的孤立的容器:
docker container prune
摘自方志朋博客,参考地址:https://www.fangzhipeng.com/docker/2018/09/12/docker-action.html
docker run -p 80:80 -d docker.io/nginx
docker cp index.html containerId://usr/share/nginx/html #用于主机和容器之间拷贝数据
docker exec -it containeId /bin/bash
docker images
docker ps [-a -q]
docker stop containerId
docker rm containerId
docker rmi imagesId
docker commit –m ’msg’ containerId [name]
docker build
docker pull
docker push
docker login
docker exec -it ubuntu /bin/bash
容器创建成功后,用户可以通过 `docker inspect` 命令查看容器的详细信息,这些详细信息包括容器的id 、容器名、环境变量、运行命令、主机配置、网络配置以及数据卷配置等信息。
例如查看unbutu的容器信息, docker inspect ubuntu
使用 format 参数可以只查看用户关心的数据,例如:
#查看容器运行状态
docker inspect -f='{{.State.Running}}' ubuntu
#查看容器IP地址
docker inspect -f='{{.NetworkSettings.IPAddress}}' ubuntu
#查看容器名称、ID
docker inspect -f='{{.Name}} {{.ID}}' ubuntu
#查看容器主机信息
docker inspect -f='{{.HostConfig}}' ubuntu
#使用 docker top 命令可以查看容器中正在运行的进程,首先确保容器已经启动,然后执行 docker top 命令,例如:
docker top ubuntu
#交互型容器查看日志很方便,因为日志就直接在控制台打印出来了,但是对于后台型容器,如果要查看日志,则可以使用docker提供的 docker logs 命令来查看,例如:
docker logs ubuntu
#默认情况下只能查看到历史日志,无法查看实时日志。使用 -f 参数后,就可以查看实时日志,使用 --tail 参数可以精确控制日志的输出行数, -t 参数则可以显示日志的输出时间,示例:
docker logs -f --tail=3 -t ubuntu
#参考命令,将nginx容器导出到/home/docker目录下
docker export nginx > /home/docker/nginx.tar
#通过执行如下命令可以导入容器(如果自己重新导入,需要记得将 docker 中和 nginx 相关的容器和镜像删除):
cat nginx.tar | docker import - importednginx:ilatest
#这里需要注意nginx.tar所在目录
#导入成功后就可以使用 docker run命令进行运行了。
#查看本地所有镜像
docker images
#如果镜像过多,可以通过通配符进行匹配
docker images n*
#可以首先通过命令查找镜像,例如:
docker search nginx
#然后可以根据查询的结果,拉取镜像到本地
docker pull nginx
#镜像可以通过 docker rmi 命令进行删除,参数为镜像的id或者镜像名,参数可以有多个,多个参数之间用空格隔开。例如:
docker rmi nginx
#如果无法删除一个镜像,大部分原因是因为该镜像被一个容器所依赖,此时需要先删除容器,然后就可以删除镜像了
# 一般采用Dockerfile方式,或者使用Jib方式去构建镜像。
# 如果是用单独Dockerfile文件方式构建镜像,可以使用如下命令:
docker build -t mk/nginx1:v2 .
# -t 参数用来指定镜像的命名空间,仓库名以及 TAG 等信息。
# 最后面的 . 是指镜像构建上下文。也就是要打包的所有内容所在路径
Docker Hub 提供镜像托管服务,类似GitHub,Docker Hub 地址为 https://hub.docker.com/
利用 Docker Hub 读者可以搜索、创建、分享和管理镜像。Docker Hub 上的镜像分为两大类,一类是官方镜像,例如nginx、mysql 等,还有一类是普通用户镜像,普通用户镜像由用户自己上传。对于国内用户,如果觉得 Docker Hub 访问速度过慢,可以使用国内一些公司提供的镜像。
例如网易:https://c.163yun.com/hub#/m/home/
接下来以Docker Hub官方镜像站来做演示如下:
# 先注册一个账户
https://hub.docker.com/
# 然后在命令行输入以下命令进行登录,提示Login Succeeded,说民登录成功
docker login
# 接下来就可以使用 push 命令上传我们自制的镜像了。注意,自制的镜像要能够上传,命名必须满足规范,即 namespace/name 格式,其中 namespace 必须是注册的用户名,例如:
docker push mk809311844265/nginx2:v2
# 然后在https://hub.docker.com/官方的Repositories中就可以看到上传的镜像了,之后可以通过pull拉下来上传的镜像文件,例如:
docker pull mk809311844265/nginx2:v2
自动化构建,就是使用 Docker Hub 连接一个包含 Dockerfile 文件的 GitHub 仓库或者 BitBucket 仓库, Docker Hub 则会自动构建镜像,通过这种方式构建出来的镜像会被标记为 Automated Build ,也称之为受信构建 (Trusted Build) ,这种构建方式构建出来的镜像,其他人在使用时可以自由的查看 Dockerfile 内容,知道该镜像是怎么来的,同时,由于构建过程是自动的,所以能够确保仓库中的镜像都是最新的。实际意义不大,因为一般的公司环境镜像都是需要保密私有的有知识产权的,所以构建本地镜像仓库就成为一个企业应用的必选方案。
Docker 官方已经将 Docker 注册服务器做成镜像了,我们直接 pull 下来运行即可。
# 第一步:拉取镜像
docker pull registry
# 第二步:实例化容器运行起来
docker run -itd --name registry -p 5000:5000 docker.io/registry
# 第三步:标记本地镜像,以nginx为例
docker tag docker.io/nginx:latest 127.0.0.1:5000/docker.io/nginx:latest
# 第四步:上传本地镜像,以nginx为例
docker push 127.0.0.1:5000/docker.io/nginx:latest
# 第五步: 查看本地仓库中的镜像
curl 127.0.0.1:5000/v2/_catalog
# 第六步: 下载本地仓库的镜像,实现使用 docker images命令查看,发现刚才push的镜像已经在本地镜像存在了,所以需要 docker rmi 命令先去删除该镜像,然后在从本地镜像仓库中下载
docker rmi 127.0.0.1:5000/docker.io/nginx
docker pull 127.0.0.1:5000/docker.io/nginx
# 特别说明,如果要在外网可以访问,需要对外开放端口访问
/sbin/iptables -I INPUT -p tcp --dport 5000 -j ACCEPT
设置私有仓库的用户名、密码(该内容不完善,未完待续)
参考如下地址:https://blog.csdn.net/qq_38637558/article/details/99603071
# 第一步:挂载相关的配置,这里注意/docker/registry/auth目录在根目录下,和home目录平级
mkdir -p /docker/registry/auth
# 第二步:生成账号密码
docker run --entrypoint htpasswd registry:latest -Bbn mk192837 mk_own_123 >> /docker/registry/auth/htpasswd
# 第三步:设置配置文件
mkdir -p /docker/registry/config
vi /docker/registry/config/config.yml ,然后输入以下内容:
================================start===================================
version: 0.1
log:
fields:
service: registry
storage:
delete:
enabled: true
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /var/lib/registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
==================================end===================================
# 第四步:启动registry容器
docker run -d -p 5000:5000 --restart=always --name=registry \
-v /docker/registry/config/:/etc/docker/registry/ \
-v /docker/registry/auth/:/auth/ \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v /docker/registry/:/var/lib/registry/ \
registry
# 第五步:开启 http 形式访问私有仓库模式
vi /etc/docker/daemon.json
# 然后添加如下内容:
{
"insecure-registries": [
"192.168.42.105:5000"
]
}
# 然后执行如下命令,使配置立刻生效
systemctl daemon-reload
# 重启docker
systemctl restart docker
# 暴露网络端口的参数有两个,分别是 `-p` 和 `-P` 。
# 使用 -P,Docker 会在宿主机上随机为应用分配一个未被使用的端口,并将其映射到容器开放的端口,以 Nginx 为例,例如:
docker run -itd --name nginx -P nginx
# 这个时候docker为应用分配了一个随机端口
# -p 参数则有几种不同的用法:
# 第一种: hostPort:containerPort 这种用法是将宿主机端口和容器端口绑定起来,示例:
docker run -itd --name nginx -p 80:80 nginx
# 第二种: ip:hostPort:containerPort 这种是将指定的 ip 地址的端口和容器的端口进行映射,将 192.168.42.1 地址的80端口映射到容器的80端口上,示例:
docker run -itd --name nginx -p 192.168.42.1:80:80 nginx
# 第三种:ip::containerPort 这种是将指定 ip 地址的随机端口映射到容器的开放端口上,示例:
docker run -itd --name nginx -p 192.168.42.1::80 nginx
# 运行nginx容器,并指定一个nginx数据卷
docker run -itd --name nginx -v /usr/share/nginx/html/ -p 80:80 nginx
# 查看数据卷映射目录
docker inspect nginx
# 如下结果,查看Mounts里的Source即可。
"Mounts": [
{
"Type": "volume",
"Name": "eab348836a0c996cdf23aea6983cf5601ec4a571b92f9e610aa19f869d09e653",
"Source": "/var/lib/docker/volumes/eab348836a0c996cdf23aea6983cf5601ec4a571b92f9e610aa19f869d09e653/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
上文中对于数据卷的用法还不是最佳方案,一般来说,我们可能需要明确指定将宿主机中的一个目录挂载到容器中,这种指定方式如下:
docker run -itd --name nginx -v /home/docker/html:/usr/share/nginx/html/ -p 80:80 nginx
这样便是将宿主机中的 /home/docker/html 目录挂载到容器的 /usr/share/nginx/html/ 目录下。接下来只需要在 /home/docker/html 目录下添加 html 文件,或者修改 html 文件,都能在 nginx 访问中立马看到效果。
这种用法对于开发测试非常方便,不用重新部署,重启容器等。
注意:宿主机地址是一个绝对路径
如果开发者使用了 Dockerfile 去构建镜像,也可以在构建镜像时声明数据卷,例如下面这样:
FROM nginx
ADD https://www.baidu.com/img/bd_logo1.png /usr/share/nginx/html/
RUN echo "hello docker volume!">/usr/share/nginx/html/index.html
VOLUME /usr/share/nginx/html/
这样就配置了一个匿名数据卷,运行过程中,将数据写入到 /usr/share/nginx/html/ 目录中,就可以实现容器存储层的无状态变化。
# 采用如下命令
docker volume ls
# 根据 volume name 可以查看数据详情
docker volume inspect f38d71202a6d55234417cede029dfa465884746c2dd4d4119a40770435950829
# 可以使用 docker volume rm 命令删除一个数据卷,也可以使用 docker volume prune 批量删除数据卷,如下:
docker volume rm f38d71202a6d55234417cede029dfa465884746c2dd4d4119a40770435950829
# 或者
docker volume prune
# 批量删除时,如果未能删除掉所有的数据卷,因为该数据卷还在使用中,将相关的容器停止并移除,再次删除数据卷就可以成功删除了
数据卷容器是一个专门用来挂载数据卷的容器,该容器主要是供其他容器引用和使用。所谓的数据卷容器,实际上就是一个普通的容器,举例如下:
# 使用如下方式创建数据卷容器:
docker run -itd -v /usr/share/nginx/html/ --name mydata ubuntu
# 使用如下命令引用数据卷容器:
docker run -itd --volumes-from mydata -p 80:80 --name nginx1 nginx
docker run -itd --volumes-from mydata -p 81:80 --name nginx2 nginx
此时, nginx1 和 nginx2 都挂载了同一个数据卷到 /usr/share/nginx/html/ 目录下,三个容器中,任意一个修改了该目录下的文件,其他两个都能看到变化。
此时,使用 docker inspect 命令查看容器的详情,发现三个容器关于数据卷的描述都是一致的。
docker run --volumes-from mydata --name backupcontainer -v $(pwd):/backup/ ubuntu tar cvf /backup/backup.tar /usr/share/nginx/html/
# 首先使用 --volumes-from 连接待备份容器。
# -v 参数用来将当前目录挂载到容器的 /backup 目录下。
# 接下来,将容器中 /usr/share/nginx/html 目录下的内容备份到 /backup 目录下的 backup.tar 文件中,由于已经设置将当前目录映射到容器的 /backup 目录,因为备份在容器 /backup 目录下的压缩文件在当前目录下可以立马看到。
备份完成后,在当前目录下就可以看到 /backup 文件,打开压缩文件,发现就是 /usr/share/nginx/html 目录及内容。
# 步骤一:创建容器
# 首先创建一个容器,这个容器就是要使用恢复的数据的容器,这里创建一个 nginx 容器,如下:
docker run -itd -p 80:80 -v /usr/share/nginx/html/ --name nginx3 nginx
# 创建一个名为 nginx3 的容器,并且挂载一个数据卷。
# 步骤二:恢复
# 数据恢复需要一个临时容器,如下:
docker run --volumes-from nginx3 -v $(pwd):/backup nginx tar xvf /backup/backup.tar
# 命令解释:
# 首先还是使用 --volumes-from 参数连接上备份容器,即第一步创建出来的 nginx3 。
# 然后将当前目录映射到容器的 /backup 目录下。
# 然后执行解压操作,将 backup.tar 文件解压。解压文件位置描述是一个容器内的地址,但是该地址已经映射到宿主机中的当前目录了,因此这里要解压缩的文件实际上就是宿主机当前目录下的文件。
一般来说,容器启动后,我们都是通过端口映射来使用容器提供的服务,实际上,端口映射只是使用容器服务的一种方式,除了这种方式外,还可以使用容器连接的方式来使用容器服务。
例如,有两个容器,一个容器运行一个 SpringBoot 项目,另一个容器运行着 mysql 数据库,可以通过容器连接使 SpringBoot 直接访问到 Mysql 数据库,而不必通过端口映射来访问 mysql 服务。
举另外一个例子:
有两个容器,一个 nginx 容器,另一个 ubuntu ,我启动 nginx 容器,但是并不分配端口映射,然后再启动 ubuntu ,通过容器连接,在 ubuntu 中访问 nginx 。
具体操作步骤如下:
docker run -d --name nginx1 nginx
容器启动成功后,在宿主机中是无法访问的。如下:
[root@node5 ~]# curl http://localhost:80
curl: (7) Failed connect to localhost:80; Connection refused
接下来,启动一个 ubuntu ,并且和 nginx 建立连接,如下:
docker run -dit --name ubuntu --link nginx1:mylink ubuntu bash
这里使用 –link 建立连接,nginx1 是要建立连接的容器,后面的 mylink 则是连接的别名。
运行成功后,进入到 ubuntu 命令行:
docker exec -it ubuntu bash
然后,有两种方式查看 nginx 的信息:
第一种
在 ubuntu 控制台直接输入 env ,查看环境变量信息:
MYLINK_ENV_NJS_VERSION=0.3.9
HOSTNAME=96efd0f2f329
MYLINK_PORT=tcp://172.17.0.4:80
MYLINK_NAME=/ubuntu/mylink
PWD=/
MYLINK_PORT_80_TCP=tcp://172.17.0.4:80
MYLINK_PORT_80_TCP_PORT=80
HOME=/root
MYLINK_PORT_80_TCP_PROTO=tcp
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
TERM=xterm
SHLVL=1
MYLINK_PORT_80_TCP_ADDR=172.17.0.4
MYLINK_ENV_PKG_RELEASE=1~buster
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYLINK_ENV_NGINX_VERSION=1.17.10
_=/usr/bin/env
可以看到 docker 为 nginx 创建了一系列环境变量。每个前缀变量是 MYLINK ,这就是刚刚给连接取得别名。开发者可以使用这些环境变量来配置应用程序连接到 nginx 。该连接是安全、私有的。 访问结果如下:
root@96efd0f2f329:/# curl http://172.17.0.4:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
第二种
另一种方式则是查看 ubuntu 的 hosts 文件: cat /etc/hosts,如下:
root@96efd0f2f329:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 mylink a918eb2fdfbc nginx1
172.17.0.3 96efd0f2f329
可以看到,在 ubuntu 的 hosts 文件中已经给 nginx1 取了几个别名,可以直接使用这些别名来访问 nginx1
root@96efd0f2f329:/# curl http://mylink
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
默认情况下,ubuntu 容器中没有安装 curl 命令,需要手动安装下,安装命令如下: apt-get update apt-get install curl
在实际的开发环境或者生产环境,容器往往都不是独立运行的,经常需要多个容器一起运行,此时,如果继续使用 run 命令启动容器,就会非常不便,在这种情况下,docker-compose 是一个不错的选择,使用 docker-compose 可以实现简单的容器编排,本文就来看看 docker-compose 的使用。
本文以 jpress 这样一个开源网站的部署为例,向读者介绍 docker-compose 的使用。jpress 是 Java 版的 wordPress ,不过我们不必关注 jpress 的实现,在这里我们只需要将之当作一个普通的应用即可,完成该项目的部署工作。
步骤一:编写Dockerfile文件
FROM tomcat
ADD jpress-v3.1.0.war /usr/local/tomcat/webapps/
RUN cd /usr/local/tomcat/webapps/ \
&& mv jpress-v3.1.0.war jpress.war
# 这里要特别注意:jpress-v3.1.0.war文件需要放在和Dockerfile同一个目录下才可以,否则build时候会报错。
# 命令解释如下:
# 1、容器基于 Tomcat 创建。
# 2、下载 jpress 项目的 war 包到 tomcat 的 webapps 目录下。
# 3、给 jpress 项目重命名。
步骤二:编写 docker-compose.yml
version: "3.1"
services:
web:
build: .
container_name: jpress
ports:
- "8080:8080"
volumes:
- /usr/local/tomcat/
depends_on:
- db
db:
image: mysql
container_name: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 123
MYSQL_DATABASE: jpress
# 这里同样要注意,需要将docker-compose.yml文件放在和Dockerfile文件相同目录下
# 命令解释如下:
# 1、首先声明了 web 容器,然后声明db容器。
# 2、build . 表示 web 容器项目构建上下文为 . ,即,将在当前目录下查找 Dockerfile 构建 web 容器。
# 3、container_name 表示容器的名字。
# 4、ports 是指容器的端口映射。
# 5、volumes 表示配置容器的数据卷。
# 6、depends_on 表示该容器依赖于 db 容器,在启动时,db 容器将先启动,web 容器后启动,这只是启动时机的先后问题,并不是说 web 容器会等 db 容器完全启动了才会启动。
# 7、对于 db 容器,则使用 image 来构建,没有使用 Dockerfile 。
# 8、restart 描述了容器的重启策略。
# 9、environment 则是启动容器时的环境变量,这里配置了数据库 root 用户的密码以及在启动时创建一个名为 jpress 的库,environment 的配置可以使用字典和数组两种形式。
步骤三:运行
# 运行命令如下:
docker-compose up -d # -d 表示在后台运行
步骤四:查看已运行的容器
# 运行命令如下:
docker-compose ps
步骤五:重启容器
# 运行命令如下:
docker restart jpress # jpress为容器名称
步骤六:停止容器
# 运行命令如下:
docker-compose down
更多使用命令可以采用 docker-compose --help 来查看帮助进行使用。
特别补充:如果使用docker-compose提示“-bash: docker-compose: command not found”,那么请按照以下说明进行docker-compose安装即可
# 方式1:
curl -L https://get.daocloud.io/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 方式2:
1)先安装 pip ,检查是否已有: pip -V
报错:
-bash: pip: command not found
安装 pip :
yum -y install epel-release
yum -y install python-pip
#升级
pip install --upgrade pip
2) 安装Docker-Compose:
pip install docker-compose
检查是是否成功:
docker-compose -version
可以参考以下链接进行详细学习:
1、Dockerfile 指令详解
https://yeasy.gitbook.io/docker_practice/image/dockerfile
2、Dockerfile指令详解 && ENTRYPOINT 指令
https://www.cnblogs.com/reachos/p/8609025.html
命令用途WORKDIRRUN ENTRYPINT CMD执行的工作目录ENV添加环境变量ADD添加文件,会解压压缩包COPY复制文件ONBUILD触发器VOLUME挂载卷FROM基础镜像ENTRYPOINT基础命令RUN执行命令CMD启动程序命令,拼接在基础命令后EXPOSE暴露端口MAINTAINER维护者
1、https://www.runoob.com/docker/docker-tutorial.html
2、http://www.javaboy.org/categories/docker/
*请认真填写需求信息,我们会在24小时内与您取得联系。