首页
留言
友情链接
壁纸
更多
关于
Search
1
dockerfile怎么执行shell脚本(利用tail -f /dev/null命令防止container启动后退出)
5,017 阅读
2
channel常见的异常总结
4,276 阅读
3
支付宝支付配置开发流程
1,431 阅读
4
HTTP 协议中的Content-Encoding
1,287 阅读
5
Laravel底层原理(二) —— 契约(Contracts)
950 阅读
PHP
composer
laravel
swoole
Docker
Linux
Go
随笔
mysql
nginx
Search
标签搜索
kratos
golang
微服务
gopher
PHP
Docker
dockerfile
通道
go
defer
alipay
支付
git
phpstorm
IDEA
web安全
漏洞
socket
设计原则
依赖注入
Royal
累计撰写
51
篇文章
累计收到
0
条评论
首页
栏目
PHP
composer
laravel
swoole
Docker
Linux
Go
随笔
mysql
nginx
页面
留言
友情链接
壁纸
关于
搜索到
51
篇与
Royal
的结果
2022-08-12
git教程及开发规范
Git简介 git是一种源码管理系统(source code management,缩写为SCM)。它对当前文件提供版本管理功能,核心思想是对当前文件建立一个对象数据库(object database),将历史版本信息存放在这个数据库中,git是目前最好用的版本控制系统(没有之一)。集中式和分布式 版本控制系统又分为集中式和分布式两种,我们熟悉的CVS及SVN都是属于集中式的版本控制系统,而git则是分布式版本控制系统,集中式和分布式版本控制系统有什么区别?集中式版本控制系统,版本库是集中存放在中央服务器的(如图一),而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器。中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”(如图二),每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了。而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。本文重点讲下分布式版本控制系统git的使用。Git安装 Git可以在Linux、Unix、Mac和Windows这几大平台上正常安装运行。安装git可以直接去官网下载安装最新的安装程序:https://git-scm.com/downloads,安装步骤这里就不再详细说。Git工作区、暂存区、版本库的工作流程 我们每天使用 git ,但是很多命令记不住。一般来说,日常使用只要记住下图(如图三)6个命令,就可以了。但是熟练使用,恐怕要记住60~100个命令,首先来了解几个概念:Workspace:工作区,就是你在电脑里能看到的目录,包括你在IDE中开发项目进行文件的添加、修改、删除等操作。Index / Stage:暂存区,英文叫stage或index。一般存放在.git目录下的index 文件(.git/index)中(如图四),所以我们把暂存区有时也叫作索引(index)。暂存区指将工作区中的操作完成小阶段的存储,是版本库的一部分。Repository:仓库区(或本地仓库),仓库区表示个人开发的一个小阶段的完成,仓库区记录的各版本是可以查看并回退的和暂存区不同的是暂存区一旦提交就再也没有了。Remote:远程仓库,简单来说就是我们搭建的git服务器gitlab或者gitee或者github代码托管平台等,存储每个成员的编码记录。用命令的方式解释下各个区是如何工作的:工作区与暂存区当对工作区修改(或新增)的文件执行git add命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。工作区到暂存区常用命令如下:git add [file1] [file2] ... # 添加一个或多个指定文件到暂存区 git add [dir] # 添加指定目录到暂存区包括子目录git add . # 添加当前目录的所有文件到暂存区git rm [file] # 同时删除工作区和暂存区的文件git rm --cached [file] # 删除暂存区的文件并保留工作区的文件git checkout . # 用暂存区全部文件替换工作区的文件git checkout -- # 用暂存区指定文件替换工作区的文件git checkout这个操作很危险,会清除工作区中未添加到暂存区中的改动。暂存区与仓库区当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。暂存到仓库区常用命令如下:git commit -m “本次提交说明” # 提交暂存区文件到本地仓库中 git reset HEAD # 移除添加到暂存区的文件,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响git reset HEAD^ # 去掉上一次的提交变成add之前的状态git reset --soft HEAD^ # 去掉上一次的提交变成add之后,commit之前的状态版本库与远程仓库当执行提交操作(git push)时,会把本地仓库中文件提交到远程仓库中,常用命令如下:git pull # 取回远程仓库的变化,并与本地分支合并git push # 上传本地指定分支到远程仓库创建版本库 了解完工作区、暂存区和本地仓库的关系之后,我们知道暂存区和本地仓库都是版本库的一部分。什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。下面我们开始git的实际操作。第一步:需要创建版本库,非常简单,直接创建一个空目录,进入空目录里面即可(以linux操作系统为例):$ mkdir testgit$ cd testgit$ pwd/root/gittest第二步:通过git init 命令把这个目录变成git可以管理的仓库;仓库建好了,当前目录下会多一个.git的目录,这个目录就是用来跟踪管理版本库的,我们也可以在其他路径使用git init <目录名称>来指定目录作为git仓库。第三步:在工作区新建文件并把文件添加到仓库;$ touch readme.txt$ vi readme.txt$ cat readme.txt hello git切记,新建文件一定要放到gittest目录(子目录)中,因为这是一个git仓库,放到其他地方git再厉害也找不到这个文件。第四步:用命令git add告诉Git,把文件添加到仓库; git add readme.txt第五步:用命令git commit告诉Git,把文件提交到本地仓库;$ git commit -m “测试git”-m:后面输入的是本次提交的说明,建议我们在开发过程中要养成习惯,输入的内容要有意义,这样能够从历史记录中轻易找到方便我们回退版本;1 file changed:1个文件被改动(我们新添加的readme.txt文件);1 insertions:插入了1行内容(readme.txt有1行内容hello git);除了以上信息之外,我们发现GIT需要我们设置名称和邮箱地址,因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。Git的配置文件为.git目录下的config文件,常用命令如下:git config --list # 显示当前的Git配置 git config [--global] user.name "[name]" # 设置提交时的用户信息git config [--global] user.email "[email address]" # 设置提交时的邮箱地址版本回退 我们现在已经知道了怎么修改文件,并且能够把修改后的文件提交到git版本库,然后我们不停的修改文件,不停的提交,通过git log命令我们可以查到我们都做了哪些提交。$ git log通过以上命令我们可以看到从最近到最远提交的日志记录,一共提交了3次,最近的一次是“测试git3 修改hello git 2023”,上一次是“测试git2 修改hello git 2022”,第一次是“测试git”,可以试试加上--pretty=oneline参数打印一次:这样是不是看得更清楚?第一段代表commit id为版本号,和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。第二段就很好理解了,代表我们提交说明,每次修改的内容是什么一目了然。假如我们现在有个需求,需要把reademe.txt回退到上一个版本,也就是测试git2 输出hello git2的哪个版本,怎么做?在git中,用HEAD表示当前版本,上一个版本是HEAD^,上上一个版本HEAD^^,往上100个版本是HEAD~100,现在回退到上一版本可以使用如下命令:$ git reset --hard HEAD^可以看到readme.txt的内容已经回退到上一版本并输出hello git 2022.假如我们现在需求变了!!需要回退到2023的版本怎么办呢?我们打印log发现2023的日志没了,这时候怎么办呢?我们使用git reflog命令来打印所有版本的commit id然后查询到git 2023的版本号为8b2cd52,再执行以下命令可以看到回退到2023的版本了。$ git reset --hard 8b2cd52Git版本回退,常用命令如下:git log --pretty=oneline # 显示历史版本 git reset --hard HEAD^ # 回退到上一版本git reflog # HEAD所指向的一个顺序的提交列表git reset --hard # 回退到指定版本号撤销修改 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令:$ git checkout -- file场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步:$ git reset HEAD 表示把暂存区的修改撤销掉,回到场景1$ git checkout -- file 表示把工作区的修改直接撤销掉场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考上节版本回退。删除文件 假如我们在工作区中删除了某个文件,会发生什么呢?现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit:现还有一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:$ git checkout -- 表示用版本库里的版本替换工作区的版本Git删除,常用命令如下:git rm # git rm就是删文件,并且把删文件的修改提交到暂存区,相当于rm删文件后,git add 提交,保存修改 添加、推送、删除远程仓 现在的情景是,你已经在本地创建了一个Git仓库后,你的代码只能在你的电脑上看到,不能跟其他同事协作开发,这时候就需要有一个远程仓库来同步我们的本地仓库,既可以作为备份,也可以让其他人通过远程仓进行协作,这就是我们开篇提到的分布式版本控制系统通常也有一台充当“中央服务器”,来交换大家的修改。第一步:添加远程仓,以gitlab为例介绍:$ git remote add origin git@172.30.1.24:webhex/cipher-php.git远程库的名字就叫origin,是可以更换的,下一步就可以把本地库的所有内容推送到远程库上了:$ git push -u origin master我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。如果想删除远程库,可以使用如下命令(使用前,建议先用git remote -v查看远程库信息):$ git remote -v 查看远程库$ git remote rm origin 删除名字是origin的远程库克隆远程仓 现在我们知道了,先在本地建立版本库,然后添加远程仓,最后实现工作区到版本库再到远程仓的协作开发,那假如我们现在从零开发,最好的方式先在gitlab、gitee或者github等建立了远程仓,怎么实现关联呢?我们只需要把远程库克隆到我们本地就能在本地同步一个本地版本仓。$ git clone git@172.30.1.24:webhex/cipher-php.git 然后我们就可以在生成的目录里面添加文件、修改文件、删除文件操作,然后如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。分支管理 git版本库创建后会默认创建一个master分支,这个分支也叫主分支。当我们需要多人协作最后合并代码,或者我们需要有测试环境、生产环境、BUG修复环境等等,这时候一个主分支已经不够用了。一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:所以Git合并分支也很快!就改改指针,工作区内容也不变!合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:Git分支管理,常用命令如下:git checkout -b dev # git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:git branch dev # 创建dev分支git checkout dev # 切换到dev分支git branch # git branch命令会列出所有分支,当前分支前面会标一个*号。git merge dev # 把dev分支合并到当前所在的分支git branch -d dev # 删除dev分支git switch -c dev # 创建切换分支同git checkout -b dev一样git switch dev # 切换到dev分支同git checkout dev分支管理策略 在实际开发中,我们应该按照几个基本原则进行分支管理:首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。所以,团队合作的分支看起来就像这样:合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。 BUG分支 软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交:并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作: git stash 首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支:$ git checkout master$ git checkout -b issue-101Switched to a new branch 'issue-101'现在修复bug,改完文件后,然后提交。修复完成后再次切换到master主分支,并完成合并,删除issue-101分支:$ git switch masterSwitched to branch 'master'$ git merge --no-ff -m "merged bug fix 101" issue-101现在,是时候接着回到dev分支干活了!用git stash list命令看看有哪些工作区:$ git stash list用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;另一种方式是用git stash pop,恢复的同时把stash内容也删了:在master分支上修复了bug后,我们要想一想,dev分支是早期从master分支分出来的,所以,这个bug其实在当前dev分支上也存在。那怎么在dev分支上修复同样的bug?重复操作一次,提交不就行了?有木有更简单的方法?有!同样的bug,要在dev上修复,我们只需要把bug分支提交的commit id找到这个提交所做的修改“复制”到dev分支。注意:我们只想复制那一个commit id这个提交所做的修改,并不是把整个master分支merge过来。Git专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支:$ git cherry-pick 多人协作 多人协作的工作模式通常是这样:1.首先,可以试图用git push origin 推送自己的修改;2.如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;3.如果合并有冲突,则解决冲突,并在本地提交;4.没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!5.如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/;6.在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致。标签管理 在Git中打标签非常简单,首先,切换到需要打标签的分支上:$ git tag v1.0可以用命令git tag查看所有标签:$ git tagv1.0默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?方法是找到历史提交的commit id,然后打上就可以了:$ git tag v0.9 注意,标签不是按时间顺序列出,而是按字母排序的。可以用git show 查看标签信息:还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:$ git tag -a v0.1 -m "version 0.1 released" 如果标签打错了,也可以删除:$ git tag -d v0.1因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。如果要推送某个标签到远程,使用命令git push origin :$ git push origin v1.0或者,一次性推送全部尚未推送到远程的本地标签:$ git push origin --tags如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:$ git tag -d v0.9然后,从远程删除。删除命令也是push,但是格式如下:$ git push origin :refs/tags/v0.9Git标签管理,常用命令如下:git tag # 用于新建一个标签,默认为HEAD,也可以指定一个commit idgit tag -a -m "blablabla..." # 可以指定标签信息git tag # 查看所有标签git push origin # 可以推送一个本地标签git push origin --tags # 可以推送全部未推送过的本地标签git tag -d # 可以删除一个本地标签git push origin :refs/tags/ # 可以删除一个远程标签git产生冲突的情况汇总 本地拉取:1)当远端有更新,本地库没有变化,拉取操作远端会覆盖本地库(远端版本高于本地)2)当远端修改,本地库也有修改,拉取操作会产生冲突文件(远端版本和本地版本冲突)3)当本地库修改,而远端没有变化,拉取不会产生变化(本地版本高于远端版本)4)当本地库版本低于远端版本,则无法推送,必须先拉取在操作,否则报错分支合并:1)当资源分支版本高于目标分支时,合并,资源分支同名文件会覆盖目标分支;2)当目标分支版本高于资源分支时,合并,提示Already up-to-date.(已经更新),目标分支内容不会变化;3)当目标分支和资源分支同名文件都有改动时,会报冲突,需手动解决; 参考资料 git官方教程https://www.runoob.com/git/git-tutorial.html阮一峰git工作流程https://www.ruanyifeng.com/blog/2015/12/git-workflow.html廖雪峰git教程https://www.liaoxuefeng.com/wiki/896043488029600/
2022年08月12日
240 阅读
0 评论
0 点赞
2022-07-05
常见的web服务器安全加固方案
常见的web服务器安全加固,以nginx和apache为例nginx安全加固在Nginx中禁用server_tokens指令,隐藏nginx错误页面显示的当前版本,避免由特定版本发起的漏洞攻击 #隐藏版本号 server_tokens off;隐藏Nginx后端服务X-Powered-By头proxy_hide_header X-Powered-By; proxy_hide_header Server;nginx进程启动账号修改为非root,降低攻击概率user www www;把控配置文件权限以抵御外来攻击修改Nginx配置文件权限:执行chmod 644 <conf_path>来限制Nginx配置文件的权限;(<conf_path>为配置文件的路径,表示拥有者有读取+写入权限,同组用户和其他用户只有读取权限上传文件大小限制10M(或者更小,根据需求而定)以内client_max_body_size 10m;在Nginx中禁用不需要的HTTP方法if ($request_method !~ ^(GET|POST)$) { return 403 'Method Forbidden'; }Nginx自定义404错误当静态资源不存在时error_page 404 @jump_to_error; location @jump_to_error { return 404 'Not Found Page'; }apache安全加固严格设置配置文件和日志文件的权限,防止未授权访问执行chmod 600 /etc/httpd/conf/httpd.conf命令设置配置文件为属主可读写,其他用户无读写权限 执行chmod 644 /var/log/httpd/*.log命令设置日志文件为属主可读写,其他用户拥有只读权限禁止Apache访问Web目录之外的任何文件Order Deny,Allow Deny from all禁止目录列出目录列出会导致明显信息泄露或下载,建议禁止Apache列表显示文件。在/etc/httpd/httpd.conf配置文件中删除Options的Indexes设置即可。如果根目录没有index.html入口文件会把目录列出来#Options Indexes FollowSymLinks #删掉Indexes 或者 Options -Indexes 隐藏Apache的版本号修改httpd.conf配置文件:apache2的配置文件中(/etc/apache2/conf-enabled)ServerSignature Off ServerTokens Prod关闭TRACE功能关闭TRACE功能,防止TRACE方法被访问者恶意利用在/etc/httpd/conf/httpd.conf配置文件中添加以下设置参数:TraceEnable Off禁用非法 HTTP 方法修改httpd.conf配置文件,只允许get、post方法。<Location /> <LimitExcept GET POST CONNECT OPTIONS> Order Allow,Deny Deny from all </LimitExcept> </Location>自定义403错误ErrorDocument 403 "Method Forbidden"Apache自定义404错误当静态资源不存在时ErrorDocument 404 “自定义错误”
2022年07月05日
417 阅读
0 评论
0 点赞
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日
530 阅读
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日
539 阅读
0 评论
0 点赞
2022-04-24
【Gopher】go语言开发环境配置goproxy(三)
在开发过程中,有时会经常遇到有些包无法完成下载的情况,网址由于墙的原因可能无法访问这时候就需要配置goproxy代理。通过go env查看默认的GOPROXY代理是官方的路径需要换成国内的代理地址。配置goproxy阿里代理go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct // Windows export GOPROXY=https://mirrors.aliyun.com/goproxy/,direct // macOS 或 Linux七牛云代理go env -w GOPROXY=https://goproxy.cn,direct // Windows export GOPROXY=https://goproxy.cn,direct // macOS 或 Linux 注意Go 1.13设置了默认的GOSUMDB=sum.golang.org,是用来验证包的有效性。这个网址由于墙的原因可能无法访问,所以可以使用下面命令来关闭:go env -w GOSUMDB=off // Windows export GOSUMDB=off // macOS 或 Linux 现在再用go build执行编译 就可以正常下载依赖包!回头发现 go的安装环境需要配置三个路径:GOROOT:go的安装目录GOPATH:项目工作目录GOPROXY:代理地址
2022年04月24日
837 阅读
0 评论
1 点赞
1
...
4
5
6
...
11