A. docker从容器中怎么访问宿主机
docker跟宿主机交互的是通过原生网络实现的。
当Docker进程启动之后,它会配置一个虚拟的网桥叫docker0在宿主机上。这个接口允许Docker去分配虚拟的子网给即将启动的容器们。这个网桥在容器内的网络和宿主机网络之间将作为接口的主节点。
Docker容器启动后,将创建一个新的虚拟接口并分配一个网桥子网内的IP地址。这个IP地址嵌在容器内网络中,用于提供容器网络到宿主机docker0网桥上的一个通道。Docker自动配置iptables规则来放行并配置NAT,连通宿主机上的docker0,就可以访问宿主机的mysql数据文件了。
B. 常见的容器安全威胁有哪些
以Docker 容器的安全问题为例
(1) Docker 自身安全
Docker 作为一款容器引擎,本身也会存在一些安全漏洞,CVE 目前已经记录了多项与 Docker 相关的安全漏洞,主要有权限提升、信息泄露等几类安全问题。
(2) 镜像安全
由于Docker 容器是基于镜像创建并启动,因此镜像的安全直接影响到容器的安全。具体影响镜像安全的总结如下。
镜像软件存在安全漏洞:由于容器需要安装基础的软件包,如果软件包存在漏洞,则可能会被不法分子利用并且侵入容器,影响其他容器或主机安全。
仓库漏洞:无论是Docker 官方的镜像仓库还是我们私有的镜像仓库,都有可能被攻击,然后篡改镜像,当我们使用镜像时,就可能成为攻击者的目标对象。
用户程序漏洞:用户自己构建的软件包可能存在漏洞或者被植入恶意脚本,这样会导致运行时提权影响其他容器或主机安全。
(3) Linux 内核隔离性不够
尽管目前Namespace 已经提供了非常多的资源隔离类型,但是仍有部分关键内容没有被完全隔离,其中包括一些系统的关键性目录(如 /sys、/proc 等),这些关键性的目录可能会泄露主机上一些关键性的信息,让攻击者利用这些信息对整个主机甚至云计算中心发起攻击。
而且仅仅依靠Namespace 的隔离是远远不够的,因为一旦内核的 Namespace 被突破,使用者就有可能直接提权获取到主机的超级权限,从而影响主机安全。
(4) 所有容器共享主机内核
由于同一宿主机上所有容器共享主机内核,所以攻击者可以利用一些特殊手段导致内核崩溃,进而导致主机宕机影响主机上其他服务。
既然容器有这么多安全上的问题,那么我们应该如何做才能够既享受到容器的便利性同时也可以保障容器安全呢?下面我带你来逐步了解下如何解决容器的安全问题。
如何解决容器的安全问题?
(1) Docker 自身安全性改进
事实上,Docker 从 2013 年诞生到现在,在安全性上面已经做了非常多的努力。目前 Docker 在默认配置和默认行为下是足够安全的。
Docker 自身是基于 Linux 的多种 Namespace 实现的,其中有一个很重要的 Namespace 叫作 User Namespace,User Namespace 主要是用来做容器内用户和主机的用户隔离的。在过去容器里的 root 用户就是主机上的 root 用户,如果容器受到攻击,或者容器本身含有恶意程序,在容器内就可以直接获取到主机 root 权限。Docker 从 1.10 版本开始,使用 User Namespace 做用户隔离,实现了容器中的 root 用户映射到主机上的非 root 用户,从而大大减轻了容器被突破的风险。
因此,我们尽可能地使用Docker 最新版本就可以得到更好的安全保障。
(2) 保障镜像安全
为保障镜像安全,我们可以在私有镜像仓库安装镜像安全扫描组件,对上传的镜像进行检查,通过与CVE 数据库对比,一旦发现有漏洞的镜像及时通知用户或阻止非安全镜像继续构建和分发。同时为了确保我们使用的镜像足够安全,在拉取镜像时,要确保只从受信任的镜像仓库拉取,并且与镜像仓库通信一定要使用 HTTPS 协议。
(3) 加强内核安全和管理
由于仅仅依赖内核的隔离可能会引发安全问题,因此我们对于内核的安全应该更加重视。可以从以下几个方面进行加强。
宿主机及时升级内核漏洞
宿主机内核应该尽量安装最新补丁,因为更新的内核补丁往往有着更好的安全性和稳定性。
使用Capabilities 划分权限
Capabilities 是 Linux 内核的概念,Linux 将系统权限分为了多个 Capabilities,它们都可以单独地开启或关闭,Capabilities 实现了系统更细粒度的访问控制。
容器和虚拟机在权限控制上还是有一些区别的,在虚拟机内我们可以赋予用户所有的权限,例如设置cron 定时任务、操作内核模块、配置网络等权限。而容器则需要针对每一项 Capabilities 更细粒度的去控制权限,例如:
cron 定时任务可以在容器内运行,设置定时任务的权限也仅限于容器内部;
由于容器是共享主机内核的,因此在容器内部一般不允许直接操作主机内核;
容器的网络管理在容器外部,这就意味着一般情况下,我们在容器内部是不需要执行ifconfig、route等命令的 。
由于容器可以按照需求逐项添加Capabilities 权限,因此在大多数情况下,容器并不需要主机的 root 权限,Docker 默认情况下也是不开启额外特权的。
最后,在执行docker run命令启动容器时,如非特殊可控情况,–privileged 参数不允许设置为 true,其他特殊权限可以使用 --cap-add 参数,根据使用场景适当添加相应的权限。
使用安全加固组件
Linux 的 SELinux、AppArmor、GRSecurity 组件都是 Docker 官方推荐的安全加固组件。下面我对这三个组件做简单介绍。
SELinux (Secure Enhanced Linux): 是 Linux 的一个内核安全模块,提供了安全访问的策略机制,通过设置 SELinux 策略可以实现某些进程允许访问某些文件。
AppArmor: 类似于 SELinux,也是一个 Linux 的内核安全模块,普通的访问控制仅能控制到用户的访问权限,而 AppArmor 可以控制到用户程序的访问权限。
GRSecurity: 是一个对内核的安全扩展,可通过智能访问控制,提供内存破坏防御,文件系统增强等多种防御形式。
这三个组件可以限制一个容器对主机的内核或其他资源的访问控制。目前,容器报告的一些安全漏洞中,很多都是通过对内核进行加强访问和隔离来实现的。
资源限制
在生产环境中,建议每个容器都添加相应的资源限制。下面给出一些执行docker run命令启动容器时可以传递的资源限制参数:
1--cpus 限制 CPU 配额
2-m, --memory 限制内存配额
3--pids-limit 限制容器的 PID 个数
例如我想要启动一个1 核 2G 的容器,并且限制在容器内最多只能创建 1000 个 PID,启动命令如下:
1 $ docker run -it --cpus=1 -m=2048m --pids-limit=1000 busybox sh
推荐在生产环境中限制CPU、内存、PID 等资源,这样即便应用程序有漏洞,也不会导致主机的资源完全耗尽,最大限度降低安全风险。
(4) 使用安全容器
容器有着轻便快速启动的优点,虚拟机有着安全隔离的优点,有没有一种技术可以兼顾两者的优点,做到既轻量又安全呢?
答案是有,那就是安全容器。安全容器是相较于普通容器的,安全容器与普通容器的主要区别在于,安全容器中的每个容器都运行在一个单独的微型虚拟机中,拥有独立的操作系统和内核,并且有虚拟化层的安全隔离。
安全容器目前推荐的技术方案是Kata Containers,Kata Container 并不包含一个完整的操作系统,只有一个精简版的 Guest Kernel 运行着容器本身的应用,并且通过减少不必要的内存,尽量共享可以共享的内存来进一步减少内存的开销。另外,Kata Container 实现了 OCI 规范,可以直接使用 Docker 的镜像启动 Kata 容器,具有开销更小、秒级启动、安全隔离等许多优点。
C. 如何配置docker远程访问 验证
前篇笔记中搞定了一个镜像并安装了jdk
本想着这tomcat会更简单,后来发现我错了。
且看下面过程:
我这个镜像原始的系统就有openssh,只需要进到镜像里 passwd一个新的密码。退出后commit一下就添加了一个ssh服务。
之后通过以下命令在后台启动镜像,执行ssh服务,开放22端口
1
docker run -d -p 22 ubuntu64:14.04 /usr/sbin/sshd -D
回车后打出容器的ID号就返回了
那我们怎么知道这容器当前什么情况呢?
1
docker ps
列出当前还在运行中的容器
能看到列表中的容器id。还有一条有用的信息是PORTS列,说明宿主机的49153映射到的容器22端口上了。
这时就可以通过putty或scp之类的连接上去进行操作了。
现在我已经把tomcat解压放到/usr/local/java目录下了。
并通过startup.sh启动测试正常.
ok exit +commit
怎么能在镜像启动时就把tomcat启起来呢??
学着之前的命令
1
docker run -it ubuntu_tomcat:7.0.55 /usr/local/java/apache-tomcat-7.0.55/bin/startup.sh
结果得到了如下的响应:
没有环境变量
进到镜像里,查看/etc/profile,明明是有的。之前通过ssh进去也是可以启动的,这是为什么呢?
linux的启动过程里,/etc/profile是在用户登录的时候执行,在命令行run的时候可能是不会进行登录操作,所以没有相应的环境变量。但是我们启动了ssh服务,从远程是通过登录进的系统,这时候就会有环境变量了。
猜出了这原因,怎么解决呢?
run命令是可以挂环境变量参数的。但是这样命令本身就会很复杂。
ok,这个时候就要Dockerfile出场了。
Dockerfile是一个用于创建镜像的工具,它的用法是这样。在当前目录建一个名为Dockerfile的文件。执行docker build:
1
docker build -t="tomcat:7.0.55" .
就会创建一个tomcat:7.0.55的镜像。
那么docker怎么知道这个镜像怎么建呢。需求要我们在Dockerfile文件中说明。
现在来看一下我这次用的Dockerfile文件的内容:
1
2
3
4
5
6
FROM ubuntu_tomcat:7.0.55
ENV JAVA_HOME /usr/local/java/jdk1.7.0_67
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH .:$JAVA_HOME/lib:$JRE_HOME/lib
ENV PATH $PATH:$JAVA_HOME/bin
CMD /usr/local/java/apache-tomcat-7.0.55/bin/catalina.sh run
FROM 指源自哪个镜像创建
ENV 指定环境变量
CMD 镜像启动时默认执行的命令,在这里我们默认把tomcat跑起来。
执行完build以后用images看一下新的镜像
启动一下。
1
docker run -d -p 80:8080 tomcat:7.0.55
把宿主机的80端口映射给镜像的8080。
再用ps命令看一下当前容器:
镜像已经正常跑起来了,端口与已经映射好了。
访问宿主机IP,就可以看到大猫图了。
用logs命令可以看到tomcat的日志。
1
docker logs ff5533
ff5533就是容器的ID
还可以用stop指令关闭容器
1
docker stop ff5533
ok,一个tomcat的服务镜像就搞定了。
D. win7怎么访问docker容器
安装Docker
借助apt-get命令,安装Docker是件轻而易举的事。
$
sudo
apt-get
install
docker.io
为了允许非根用户也可以运行Docker,将你自己添加到docker群组。下面这个命令会允许当前用户运行Docker,无需根用户权限。
$
sudo
usermod
-a
-G
docker
$USER
退出,然后重新登录,以激活群组成员的变化。
下一步,编辑Docker配置文件,以便更新Docker二进制代码的位置。
$
sudo
vi
/etc/default/docker.io
DOCKER="/usr/bin/docker.io"
重启Docker服务。
$
sudo
service
docker.io
restart
管理Docker容器
如果你想启动Ubuntu操作系统的一个新的Docker容器,首先需要获取Ubuntu
Docker映像文件。下面这个命令会通过网络下载Docker映像文件。
$
docker
pull
ubuntu
你可以以一种交互模式来开启Ubuntu
Docker,如下所示。最后一个参数“/bin/bash”是一旦启动就将在容器里面执行的命令,这里是一个简单的bash外壳命令。
$
docker
run
-i
-t
ubuntu
/bin/bash
E. Docker安全性――Docker容器真的安全吗
我听到和读到了很多人假定Docker的容器实际上是沙箱利用程序,这意味着他们可以在他们的系统以root身份运行的Docker随机的利用程序。他们相信Docker容器实际上保护他们的主机系统。
?我听到有人说,Docker容器一样是安全的,由于在不同的虚拟机/ KVM正在运行的进程。
?我知道人们正在下载随机Docker镜像,然后启动他们自己的主机上。
?我乃至看到的PaaS服务器(还不是OpenShift)可让用户上传自己的照片,以在多租户系统上运行。
?我有1个同事谁说:“Docker行将运行从Internet下载的随机代码,并作为root运行它”
“你能走进我的客厅里?”蜘蛛对苍蝇说。
停止假定Docker和Linux内核保护你免受歹意软件侵害。
你关心吗?
如果你是否是在多租户系统运行Docker,你正在使用1个容器中运行的服务,良好的安全实践,你或许其实不需要担心。姑且认为在容器内运行的特权进程是相同的运行在容器外部特权进程。
有些人做容器的认为比正在运行的虚拟机的更好,更快的方法的毛病。从安全的角度来看,容器要弱很多,我将在本文后面掩盖。
如果你相信,我这样做, - 意思视为运行Apache你把Apache服务的系统上运行的方式相同容器中Docker的容器应被视为“容器服务”,这意味着你会做以下几点:
?尽快删除权限
?尽量以非root运行您服务
?容器内招待root,就好像它是root容器的之外
目前,我们正在告知人们在1般条件到1个容器内处理权限的进程具有相同条件的容器外运行的特权进程。
不要在系统上运行随机的Docker图象。在很多方面我看Docker容器革命类似于1999年左右的Linux的革命。在那个时候,当管理员听到1个新酷Linux的服务,他们会:
?在像rpmfind.net的地方或只是随机的的网站在Internet上搜索包
?下载程序到他们的系统
?如果通过RPM安装或使安装
?与特权运行它
怎样会错呢?
两个星期后,管理员听到关于zlib的脆弱性和具有弄清楚,如果,同时希望并祈祷这不是,他们的软件是脆弱的!
这是Red Hat分发等少数可信方已加强在改变败局。红帽企业Linux管理员提供:
?1个值得信赖的存储库,他们可以从下载软件
?安全更新修复漏洞
?1个安全响应小组发现和管理漏洞
?1个工程师团队来管理/保护包和安全增强工作
?通用标准认证检查操作系统的安全性
仅运行可信方容器。我相信你应当继续从谁你已从过去得到它1样的人得到您的代码/包。如果代码不是来自内部或受信任的第3方,不靠容器技术来保护你的主机。
那末,问题是甚么?为何容器中不包括那些内容?
最大的问题就是1切在Linux中没有命名空间。目前,Docker使用5个命名空间来改变系统的流程视图:进程,网络,安装,主机名,同享内存。
虽然这些给用户的安全性的某种程度它绝不是全面,像KVM。在KVM环境中虚拟机进程不跟主机内核直接。他们没有任何访问内核的文件系统,如/ sys和/sys/fs, /proc/*。
装备节点用来交换内核的虚拟机不是主机。因此,为了有1个特权提升了虚拟机,该进程必须subvirt(1个基于虚拟机的后门)虚拟机的内核,发现在管理程序中的漏洞,通过SELinux的控制突破(sVirt),这是非常紧的在虚拟机上,最后攻击主机内核。
当你在1个容器中运行你已读懂了你在哪里聊到主机内核。
主要的内核子系统都没有命名空间,如:
?SELinux的
?cgroup中
?在/ sys下的文件系统
?/proc/sys, /proc/sysrq-trigger, /proc/irq, /proc/bus
装备没有命名空间:
?/ dev/ MEM
?/ dev/ SD*文件系统装备
?内核模块
如果你能沟通或攻击的其中之1作为特权的进程中,你可以具有自己的系统。
F. 有哪些问题使用docker解决不掉
1 系统方面
docker可以运行各版本的linux,但唯独windows系统无法直接运行
2进程方面
docker运行进程1的初始化服务需要特权模式,所有root是共享进程的,无法单独root用户运行
3 资源方面
无法直接独占硬件资源,且对单容器网络流量和速度控制目前没有很好的支撑方案
4 安全方面
docker并不是虚拟机,目前仍然有漏洞可以通过操作docker所在宿主机
5 监控方面
无法监控docker所在硬盘分区,往往对其监控是基于宿主机的硬盘监控。cpu和内存的资源因为是共享指定,不通过压力测试无法直接监控所使用的cpu和内存资
6 网络访问
docker无法直接通过内部ip互相访问,跨宿主机容器访问需要借助第三方工具如weave等解决方案
7 host文件
docker容器内的host文件修改后,重启会消失,因为启动容器时候host是重新从宿主机加载的。如果要重启不变,需要在启动容器时命令指定
8 固定ip
docker默认情况内部ip地址会发生变化,固定ip需要单独命令指定
9 端口
除非host模式,否则默认docker容器内部的所有端口外部无法直接访问,需要启动容器时命令里指定端口映射
另外,启动容器后再新增端口映射是不允许的,如需要增加可通过iptables的nat间接实现
暂时想到这么多,希望可以帮到你
G. 如何访问docker容器的web
需要前目录建立三文件
1).gitignore
node_moles/*
2)package.json
{
"name": "docker-centos-hello",
"private": true,
"version": "0.0.1",
"description": "Node.js Hello world app on CentOS using docker",
"author": "Daniel Gasienica ",
"dependencies": {
"express": "3.2.4"
}
}
3)server.js
var express = require('express'),
app = express(),
redis = require('redis'),
RedisStore = require('connect-redis')(express),
server = require('http').createServer(app);
app.configure(function() {
app.use(express.cookieParser('keyboard-cat'));
app.use(express.session({
store: new RedisStore({
host: process.env.REDIS_HOST || 'localhost',
port: process.env.REDIS_PORT || 6379,
db: process.env.REDIS_DB || 0
}),
cookie: {
expires: false,
maxAge: 30 * 24 * 60 * 60 * 1000
}
}));
});
app.get('/', function(req, res) {
res.json({
status: "ok"
});
});
var port = process.env.HTTP_PORT || 3000;
server.listen(port);
console.log('Listening on port ' + port);
配置Dockerfile
我需要通Dockerfile配置我docker镜像
FROM ubuntu:14.04
MAINTAINER zengjinlong
RUN apt-get update
#Install Redis
RUN apt-get -y -qq install python redis-server
RUN apt-get -y -qq install wget
#Install Node
RUN cd /opt && \
wget && \
tar -xzf node-v0.10.33-linux-x64.tar.gz && \
mv node-v0.10.33-linux-x64 node && \
cd /usr/local/bin && \
ln -s /opt/node/bin/* . && \
rm -f /opt/node-v0.10.33-linux-x64.tar.gz
#Set the working directory
WORKDIR /src
j
CMD ["/bin/bash"]
Dockerfile通docker build建立我镜像
docker build -t minimicall/node_web:0.1 .
需要说明需要灵根据ubuntu真实环境变化间指令例,我第执行候告诉我找python redis-server我想应该我apt 源太out所我加RUN apt-get update.解决问题
我wget候说没指令我安装wget.nodejs址我nodejs官网查找所碰问题具体问题具体析
查看我建立镜像
micall@micall-ThinkPad:~/docker/nodejs_web_app$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
minimicall/node_web 0.1 730770dff17f 6 minutes ago 268.7 MB
centos centos6 70441cac1ed5 2 weeks ago 215.8 MB
ubuntu 14.04 5506de2b643b 4 weeks ago 199.3 MB
启我镜像:
sudo docker run -i -t --rm \
> -p 3000:3000 \
> -v `pwd`:/src \
> minimicall/node_web:0.1
候我已经进入镜像启容器面
root@d80a2ed6b4c0:/src#
执行列命令
root@d80a2ed6b4c0:/src# npm install --quiet > /dev/null
npm WARN engine [email protected]: wanted: {"node":"<0.9.0"} (current: {"node":"0.10.33","npm":"1.4.28"})
root@d80a2ed6b4c0:/src# npm install -g nodemon --quiet > /dev/null
root@d80a2ed6b4c0:/src# ls
Dockerfile Dockerfile~ index.js~ package.json server.js src
Dockerfile.centos index.js node_moles package.json~ server.js~
root@d80a2ed6b4c0:/src# nodemon server.js
22 Nov 14:37:31 - [nodemon] v1.2.1
22 Nov 14:37:31 - [nodemon] to restart at any time, enter `rs`
22 Nov 14:37:31 - [nodemon] watching: *.*
22 Nov 14:37:31 - [nodemon] starting `node server.js`
Listening on port 3000
候用浏览器打:结
{
"status": "ok"
}
H. 访问Docker容器有哪些方法
docker attach
docker exec
I. 如何解决docker宿主机无法访问容器中的服务
1、每个镜像都定义了可对外提供的接口,Nginx镜像只默认提供了80和443端口,你自然无法访问到容器内的8080端口。
2、只需要在docker create或者docker run创建容器时携带--expose参数,就能把指定的端口开放出来。
--expose Expose a port or a range of ports