首页
留言
友情链接
壁纸
更多
关于
Search
1
dockerfile怎么执行shell脚本(利用tail -f /dev/null命令防止container启动后退出)
4,942 阅读
2
channel常见的异常总结
4,259 阅读
3
支付宝支付配置开发流程
1,403 阅读
4
HTTP 协议中的Content-Encoding
1,251 阅读
5
Laravel底层原理(二) —— 契约(Contracts)
939 阅读
PHP
composer
laravel
swoole
Docker
Linux
Go
随笔
mysql
nginx
Search
标签搜索
gopher
Docker
PHP
dockerfile
通道
go
defer
alipay
支付
git
phpstorm
IDEA
web安全
漏洞
socket
Royal
累计撰写
35
篇文章
累计收到
0
条评论
首页
栏目
PHP
composer
laravel
swoole
Docker
Linux
Go
随笔
mysql
nginx
页面
留言
友情链接
壁纸
关于
搜索到
6
篇与
Docker
的结果
2022-06-23
浅谈docker的几种网络模式
最近项目在做安全加固的时候突然遇到一个问题,一共三个板卡,每个板卡上面部署了三套执行体(php,java,python各一套),要求同一个板卡上面的三个执行体的容器彼此之间隔离,不能互相通信,也不能使用ping命令。解决这个问题之前,我们先了解下docker的网络通信模式有哪些?docker容器的通信模式分类通过命令查看docker安装后默认的网络模式列表docker network ls通过打印发现一共包含bridge桥接模式,host主机模式、none三种默认的模式,其实还有另外两种是默认不显示的,需要手动定以后,才能通过docker network ls命令查看才会显示出来!模式名称简介备注bridge容器拥有独属于自己的虚拟网卡和和虚拟IP等网络资源,它们分别通过docker0虚拟网卡与宿主机的eth0网卡交互,进而和外界网络交互默认模式host容器没有自己的任何独立的网络资源(比如:容器的IP、网卡和端口),完全和宿主机共享网络空间弊端:同一个端口只能同时被一个容器服务绑定none该模式关闭了容器的网络功能,仅有独自的网络空间(一个空架子),并且该模式不会给容器分配任何网络资源,包括虚拟网卡、路由、防火墙、IP、网关、端口等光秃秃的一个容器,没有任何的网络资源,就是自娱自乐的光杆司令(很少用)container它是bridge和host模式的合体,优先以bridge方式启动启动第一个容器,后面的所有容器启动时,均指定网络模式为container,它们均共享第一个容器的网络资源,除了网络资源,其他资源,容器彼此之间依然是相互隔离的第一个以bridge方式启动的容器服务挂掉,后面依赖它的容器,都暂停服务自定义该模式也更为灵活,可以通过-d 指定自定义的网络模式的类型,可以是bridge或者overlay,其中overlay功能更为强大,可以指定多个subnet子网网段。该模式,在容器之间使用别名相互通信,有着举足轻重的作用(重要)通过这个表我们发现,docker的容器的通信模式一共有5种,默认采用的是bridge桥接模式,我们再来看下这5种模式怎么使用。网络模式的使用方式docker run 后面添加 --net参数即可。--net=bridge 采用桥接方式--net=host 采用主机模式--net=container 采用容器模式--net=none 采用独立的无网络模式该采用哪种模式才能实现容器之间的隔离我们先来看下目前我们采用的哪种网络模式,通过docker inspect打印容器信息,发现我们容器运行模式位host模式。通过启动命令我们也能发现我们采用了host主机模式docker run -dit --net=host --privileged=true --restart=always --name=debian_nginx_ci_v1 -e MIMIC_BRACKET_HOST="32.60.90.42" -e MIMIC_BRACKET_PORT="8091" debian_nginx_ci:v1什么是主机模式呢?主机模式意味着容器和宿主机共享Network namespace从上图可以看出,如果在启动容器后使用的是host模式,那么这个容器将不会获得一个独立的Network Namespace(网络命名空间),而是和宿主机系统共用一个Network Namespace。并且这就意味着容器将不会虚拟出自己的网卡以及配置自己的ip等,而是使用宿主机的ip以及端口。不过呢,在其他方面例如文件系统等还是与之隔离的。这种方式最大优势在于网络性能比较好,网络传输速率高。但是缺点也很明显——网络的隔离性很弱。而且这种host模式还有个最大的劣势就是容器的端口不能重复占用,一旦宿主机上某个端口被占用,那么容器就不能在使用。比如宿主机上有个nginx占用了80,那么容器的nginx就不能在使用80端口了。因此这种方式是无法实现我们开篇说的容器彼此之间隔离,不能互相通信,也不能使用ping命令的需求。我们再来看下container模式满足么?它是bridge和host模式的合体,优先以bridge方式启动启动第一个容器,后面的所有容器启动时,均指定网络模式为container,它们均共享第一个容器的网络资源, 除了网络资源 ,其他资源,容器彼此之间依然是相互隔离的很显然这种方式也不行!!那么只剩下最后一种bridge模式了什么是bridge模式?该模式就是我们在启动docker服务后默认的docker网络模式,其会在主机上创建一个名为docker0的虚拟网桥,这个主机上的所有启动的容器就会连接到这个虚拟网桥上。docker0和自定义网络肯定不通,我们是使用自定义网络的好处就是网络隔离:bridge模式的使用 我们先通过自定义创建网络的方式,创建一个php的网络,指定子网、IP地址范围、网关等网络配置docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 php通过docker network ls查看是否创建成功可以看到多了一个php的网络,查看自定义网络细节docker network inspect php注:如果创建网络时候报以下错误,是因为docker服务启动之后开启了防火墙需要重启docker服务systemctl restart firewalld.service然后我们再用同样的方法创建一个python服务的网络如果在创建的过程中报Error response from daemon: Pool overlaps with other one on this address space 说明网段被占用,换一个网段即可。然后分别启动php的容器和python的容器并指定到对应的网络docker run -dit --net=php --privileged=true --restart=always --name=ubuntu_apache_ci_v1 -e MIMIC_BRACKET_HOST="33.60.90.43" -e MIMIC_BRACKET_PORT="8091" ubuntu_apache_ci:v1 docker run -dit --restart=always --net=python --privileged=true --name=cm_ca_env cm_ca_env:v1我们先进入php的服务容器中拿到对应的ip地址如下:可以看到php的容器的ip地址为192.168.0.2/16再进入到python的服务容器中,通过curl方式和ping的方式来请求php的服务发现都是不通的。我们再来验证下,同一网络内的容器是否互通呢?我们把python的服务删掉,然后重新启动使用php的网络。进入到容器中再试下结果:总结 可以看到,在python的容器中不管是连接php的服务还是自己容器内的服务都是想通的,因此得出结论,如果需要保证同一宿主机上的容器彼此服务隔离必须采用bridge的模式,并且不能使用同一自定义网络(同一网段)。Docker网络bridge桥接模式,是创建和运行容器时默认模式。这种模式会为每个容器分配一个独立的网卡,桥接到默认或指定的bridge上,同一个Bridge下的容器下可以互相通信的。我们也可以创建自定义bridge以满足个性化的网络需求,保证了一个容器代码被篡改,不会波及到其他服务。解决bridge模式下外网访问问题 我们先来看下bridge模式下的一些特性:docker run 命令不带--net参数时,默认就是桥接模式。桥接模式下容器的虚拟IP,容器内部彼此之间可以访问,非宿主机的其他其他主机无法直接访问容器内部的服务。桥接模式下,虽然外界主机不能直接访问宿主机容器内部的服务,但是可以通过间接方式访问宿主机docker run -p时,对外暴露的映射端口。因此使用-p 宿主机端口:容器端口映射的方式,通过访问宿主机端口而不能直接访问容器端口的形式来访问!
2022年06月23日
507 阅读
0 评论
0 点赞
2022-06-01
如何在docker容器启动时动态更换项目中的配置项
需求最近在部署项目时发现项目代码中有依赖的其他服务的ip和端口号,但是需要部署在三台不同的服务器上,每台服务器上的ip地址和端口号都不一样,这就需要打包三份不同的镜像分别部署,那有没有其他办法来完成动态更改呢?当然有,只需要以下四步搞定。dockerfile的环境变量我们首先想到了dockerfile里面有个关键词ENV,官方给的解释是如下:设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。格式:ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...首先我们在dockerfile编写时设置环境变量,比如我要把ip和端口定义环境变量如下:# base image FROM ubuntu_apache_ci:latest # MAINTAINER MAINTAINER sangshuaidong <sangshuaidong@comleader.com.cn> RUN rm -rf /home/wwwroot/default/* \ && rm -rf /home/wwwroot/ci.localhost.com/* \ && rm -rf /usr/local/apache/conf/httpd.conf \ && rm -rf /usr/local/php/etc/php.ini \ && rm -rf /usr/local/apache/conf/extra/httpd-vhosts.conf # COPY COPY ci.localhost.com/ /home/wwwroot/ci.localhost.com/ COPY ["start.sh", "/root/start.sh"] COPY ["httpd.conf", "/usr/local/apache/conf/httpd.conf"] COPY ["httpd-vhosts.conf", "/usr/local/apache/conf/extra/httpd-vhosts.conf"] COPY dist* /home/wwwroot/default/ ENV MIMIC_BRACKET_HOST 192.168.22.113 ENV MIMIC_BRACKET_PORT 8091 RUN chmod -R 777 /home/wwwroot/ \ && chmod -R 777 /root/start.sh WORKDIR /root #CMD CMD ["/bin/bash","./start.sh"] EXPOSE 8000 443 9000 上面我们定义了两个环境变量MIMIC_BRACKET_HOST和MIMIC_BRACKET_PORT,这样我们就可以容器中使用,在配置文件中使用唯一变量名替代比如我们的项目配置文件在config文件夹下,我们把我们的配置项参数值修改为唯一名MIMIC_BRACKET_HOST_ENV和MIMIC_BRACKET_PORT_ENV,要确保这个名字在改文件内为唯一的这样才能方便我们后面替换!!在启动脚本文件内使用正则表达式进行环境变量替换sed -i -e "s#MIMIC_BRACKET_HOST_ENV#${MIMIC_BRACKET_HOST}#" /home/wwwroot/ci.localhost.com/application/config/access.php sed -i -e "s#MIMIC_BRACKET_PORT_ENV#${MIMIC_BRACKET_PORT}#" /home/wwwroot/ci.localhost.com/application/config/access.php 上面的意思就是把配置文件内的字符MIMIC_BRACKET_HOST_ENV和MIMIC_BRACKET_PORT_ENV换成我们镜像的环境变量完成以上几步就可以使用docker build构建镜像了,注意:大家在写dockerfile时尽量遵循规则,避免重复多层,因为每一条命令在构建时就会新增一层,层数越大镜像自然也就越大!启动容器docker run -dit --net=host --privileged=true --name=ubuntu_apache_ci_v1 -e MIMIC_BRACKET_HOST="1.1.1.1" -e MIMIC_BRACKET_PORT="8888" ubuntu_apache_ci:v1使用-e 参数 把我们要修改的变量通过参数传递进去,如果不指定参数的话,默认就会按照dockerfile里面的默认值。我们进去容器看下效果:docker exec -it adb67edebffd /bin/bash 可以看到配置项已经更改,这样就可以解决我们在不同服务器上使用同一套镜像了,避免了频繁修改配置参数重复打包的工作!
2022年06月01日
522 阅读
0 评论
0 点赞
2022-04-18
dockerfile怎么执行shell脚本(利用tail -f /dev/null命令防止container启动后退出)
最近在测试应用通过docker容器部署时发现,容器启动后无法自动启动NGINX和PHP程序,需要进入到容器内部来完成nginx和php的启动。具体的指令就是: docker exec -it 容器ID /bin/bash /usr/local/nginx/sbin/nginx #启动nginx /usr/local/php7/sbin/php-fpm #启动php ps -ef | grep 'nginx' ps -ef | grep 'php'通过以上指令才能完成容器内部的程序启动,那有没有办法在启动docker容器时自动启动内部程序运行呢?当然有!通过运行shell脚本的方式:我们在Dockerfile的同级目录下创建一个shell脚本,名字为start.sh编写start.sh文件#!/bin/bash /usr/local/php7/sbin/php-fpm /usr/local/nginx/sbin/nginx然后我们重新编写Dockerfile文件# base image FROM ci:latest # MAINTAINER MAINTAINER sangshuaidong <sangshuaidong@comleader.com.cn> # COPY COPY ci.localhost.com* /www/ COPY ["start.sh", "/root/start.sh"] RUN chmod -R 777 /www/ WORKDIR /root #CMD CMD ["/bin/bash","./start.sh"]注释:COPY脚本文件start.sh到我们容器内部的root目录下,然后设置工作目录为root,然后通过CMD命令来运行start.sh文件.我们先来看下CMD命令是用来做什么的?类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:CMD 在docker run 时运行。RUN 是在 docker build。作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。COMMAND为docker容器的默认启动命令,查看容器镜像的Dockerfile,一般体现为 CMD ["命令"] ,如 CMD ["/bin/bash"]每个容器都会有一个 pid 为 1 的进程,如果这个进程执行结束了,容器也就 close 了;COMMAND 为 /bin/bash, 说明这个容器的初始进程就是 bash 进程;默认情况下,docker logs <container_id> 也只会打印 pid 为 1 进程的输出现在我们打包镜像,运行一下容器看看是否可以正常启动php和nginx服务docker build -t ci:v3 . docker iamges启动容器:docker run -dit -p 8080:80 -p 443:443 -p 9000:9000 --privileged=true --name=civ3 ci:v3 docker ps 我们发现容器没有启动成功,这是为什么呢?我们分析下:container 刚起来的时候,用户可以通过 dockerfile 中的 CMD,ENTRYPOINT,或者直接在 docker run 后面接 comand,来指定 container 启动时执行的程序。如果指定的程序只是一个短暂的任务,比如 echo sorry。那么,sorry,container 在输出 “sorry” 之后,就退出了。可以通过 docker inspect 看到,container 状态变成了 Exited。docker build Dockerfile后,采用docker run –name xxx -d 运行容器,发现start.sh执行后容器就退出了,根本无法启动nginx和php。分析了一下docker的机制,一个docker容器同时只能管理一个进程,这个进程退出后,容器也就退出了。这并不意味着一个容器里只能同时运行一个进程(那样太浪费了),只是最后一个运行的进程不能退出。start.sh总结总结:容器中运行多个守护进程时,前面的进程要用后台方式运行(或添加 &),否则后面的服务无法启动容器中最后一个守护进程一定要用前台方式运行,否则start.sh退出,容器退出,所有的服务就白启动解决方法 可以利用tail -f /dev/null让容器一直处于runing状态,用CMD 执行一个脚本,在脚本中启动多个服务。例如我们要执行start.sh这个脚本,利用这个脚本启动主服务,并执行tail -f /dev/null:我们重新编写start.sh文件 只需要在末尾加上tail -f /dev/null#!/bin/bash /usr/local/php7/sbin/php-fpm /usr/local/nginx/sbin/nginx tail -f /dev/null然后我们重新按照上面流程打包镜像,启动容器即可!发现 php和nginx程序都是运行状态!那除了shell脚本方式运行 还有其他方式么?待更....
2022年04月18日
4,942 阅读
0 评论
0 点赞
2021-07-16
使用docker lnmp镜像包部署搭建laravel项目
#更新yum软件管理器 yum -y update#安装docker yum install -y docker#配置docker加速器 curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io修改docker的配置文件vi /etc/docker/daemon.json配置一下CDN在/etc/resolv.conf文件中新增一个参数然后重启docker service docker restart查看docker版本确认是否安装成功docker version搜索LNMP镜像docker search LNMP 选取stars最多的镜像作为环境拉取镜像docker pull 2233466866/lnmp问题1 :拉取镜像时会报以下错误Get https://registry-1.docker.io/v2/: read tcp 192.168.174.128:49316->3.229.227.53:443: read: connection reset by peer 解决 :Docker Error response from daemon: Get https://registry-1.docker.io/v2/: read tcp的问题首先:通过dig @114.114.114.114 registry-1.docker.io找到可用IP配置找到的可用ip:修改hosts文件vi /etc/hosts添加进刚才找的可用ip:52.87.94.70 registry-1.docker.io保存退出即可 问题2 :拉取镜像太慢 解决 :登录阿里云后,访问https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,会看到加速器地址,复制下来,执行后面的命令。#编辑 /etc/docker/daemon.json 配置文件 将复制出来的阿里云加速器地址添加到json数组中 { "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] } #重启 Docker 服务 systemctl daemon-reload systemctl restart docker #检查是否生效 docker info 结果中显示了我们设置的镜像服务器地址,则说明设置已经生效查看镜像是否拉取成功docker images可以看到拉取成功!启动容器docker run -it --privileged --name=lnmp -p 20016:80 -p 3306:3306 -v ~/www:/www -v ~/lnmp-data/env/mysqlData:/data/mysql -v ~/lnmp-data/env/nginx.conf:/usr/local/nginx/conf/nginx.conf 2233466866/lnmp问题1 :启动容器时会报以下错误:/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "container init exited prematurely原因 : linux 与 docker 版本的兼容性问题,可以尝试重新安装 docker 或者升级linux内核解决 :第一种:yum update解决 :第二种:升级docker版本1.卸载旧版本 docker yum remove docker docker-common docker-selinux dockesr-engine -y 2.升级系统软件 yum upgrade -y 3.安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 4.添加软件源信息 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 5.更新并安装 docker-ce yum makecache fast yum install docker-ce -y 6.启动服务 systemctl daemon-reload systemctl restart docker说明:~/www 是工作目录~/lnmp-data/env/mysqlData 是数据库目录~/lnmp-data/env/nginx.conf 是nginx是配置文件20016是本地端口我的一个项目 目录是~/www/wwwroot/laravel,所以nginx.conf配置文件的内容如下:user www; worker_processes auto; worker_cpu_affinity auto; pid logs/nginx.pid; events { worker_connections 102400; } http { charset utf-8; server_tokens off; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; include mime.types; default_type application/octet-stream; client_max_body_size 20M; sendfile on; keepalive_timeout 20; gzip on; gzip_vary on; gzip_comp_level 1; gzip_types text/css application/javascript application/json image/png image/webp image/apng image/jpeg image/x-icon; error_log /www/z_error.log; access_log /www/z_$host.log main; server { listen 80; server_name www.test.com; root /www/wwwroot/laravel/public; index index.html index.htm index.php autoindex on; location / { index index.php index.html index.htm; try_files $uri $uri/ /index.php?$query_string; } location ~* \.php { include fastcgi_params; fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; fastcgi_split_path_info ^(.+\.php)(.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } }其他命令docker ps -a 查看所有容器 docker stop ****** 停止运行容器 docker rm ***** 删除容器(删除前需停掉)
2021年07月16日
492 阅读
0 评论
0 点赞
2021-04-22
dockerfile编写日记
基于Dockerfile构建镜像Dockerfile:source code for building Docker fileDocker可以通过从Dockerfile文件中读取指令自动构建镜像Dockerfile是一个文本文档,它包含用户可以在命令行上调用的所有命令来组装映像使用Docker build命令,用户可以通过逐条执行几条命令自动创建镜像
2021年04月22日
243 阅读
0 评论
0 点赞
1
2