一、初识docker
1.1 LXC介绍
LXC为LinuX Container的简写。Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与传统虚拟化技术相比,它的优势在于:
与宿主机使用同一个内核,性能损耗小;
不需要指令级模拟;
不需要即时(Just-in-time)编译;
容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;
避免了准虚拟化和系统调用替换中的复杂性;
轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。
总结:Linux Container是一种轻量级的虚拟化的手段。
1.2 docker简介
Docker是Docker.lnc公司开源的一个基于LXC技术之上构建的contailer容器引擎,源代码托管在github上,基于go语言并遵从Apache2.0协议开源。
Docker是通过内核虚拟化技术(namespace及cgroups等)来提供容器的资源隔离与安全保障等,由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机VM额外的操作系统开销,提高资源利用率。
下图比较了Docker和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复制本地主机的操作系统,而传统方式则是在硬件层面实现。
1.3 docker的工作模式
学习Docker的源码并不是一个枯燥的过程,反而可以从中理解Docker架构的设计原理。
Docker对使用者来讲是一个C/S模式的架构,而Docker的后端是一个非常松耦合的架构,模块各司其职,并有机组合,支撑Docker的运行。
用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者。而Docker Daemon作为Docker架构中的主体部分,首先提供Server的功能使其可以接受Docker Client的请求;而后Engine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式的存在。
Job的运行过程中,当需要容器镜像时,则从Docker Registry中下载镜像,并通过镜像管理驱动graphdriver将下载镜像以Graph的形式存储;当需要为Docker创建网络环境时,通过网络管理驱动networkdriver创建并配置Docker容器网络环境;当需要限制Docker容器运行资源或执行用户指令等操作时,则通过execdriver来完成。而libcontainer是一项独立的容器管理包,networkdriver以及execdriver都是通过libcontainer来实现具体对容器进行的操作。当执行完运行容器的命令后,一个实际的Docker容器就处于运行状态,该容器拥有独立的文件系统,独立并且安全的运行环境等。
CLI交互模型
Remote API 交互模型
二、Docker的三大核心概念
2.1 镜像
Docker镜像(Image)类似于虚拟机的镜像,可以将他理解为一个面向Docker引擎的只读模板,包含了文件系统。
例如:一个镜像可以完全包含了Ubuntu操作系统环境,可以把它称作一个Ubuntu镜像。镜像也可以安装了Apache应用程序(或其他软件),可以把它称为一个Apache镜像。
镜像是创建Docker容器的基础,通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像。用户可以从网上下载一个已经做好的应用镜像,并通过命令直接使用。
总之,应用运行是需要环境的,而镜像就是来提供这种环境。
2.2 容器
Docker容器(Container)类似于一个轻量级的沙箱子(因为Docker是基于Linux内核的虚拟技术,所以消耗资源十分少),Docker利用容器来运行和隔离应用。
容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些容器都是相互隔离、互不可见的。
可以把每个容器看作一个简易版的Linux系统环境(包括了root用户权限、进程空间、用户空间和网络空间),以及与运行在其中的应用程序打包而成的应用盒子。
镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身将保持不变。就像用ISO装系统之后,ISO并没有什么变化一样。
2.3 仓库
Docker仓库(Repository)类似于代码仓库,是Docker集中存放镜像文件的场所。
有时候会看到有资料将Docker仓库和注册服务器(Registry)混为一谈,并不严格区分。实际上,注册服务器是存放仓库的地方,其上往往存放着多个仓库。每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。例如存放Ubuntu操作系统镜像的仓库,称为Ubuntu仓库,其中可能包括14.04,12.04等不同版本的镜像。
根据存储的镜像公开分享与否,Docker仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
目前,最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,可以提供稳定的国内访问。
如果用户不希望公开分享自己的镜像文件,Docker也支持用户在本地网络内创建一个只能自己访问的私有仓库。当用户创建了自己的镜像之后就可以使用push命令将它上传到指定的公有或者私有仓库。这样用户下次在另一台机器上使用该镜像时,只需将其从仓库pull下来就可以了。
三、对比docker和虚拟化
类别 |
Docker |
OpenStack |
部署难度 |
非常简单 |
组件多,部署复杂 |
启动速度 |
秒级 |
分钟级 |
执行性能 |
和物理系统几乎一致 |
VM会占用一些资源 |
镜像体积 |
镜像是MB级别 |
虚拟机镜像GB级别 |
管理效率 |
管理简单 |
组件相互依赖,管理复杂 |
隔离性 |
隔离性高 |
彻底隔离 |
可管理性 |
单进程、不建议启动SSH |
完整的系统管理 |
网络连接 |
比较弱 |
借助Neutron可以灵活组建各类网络架构 |
四、Docker八种应用场景
1)简化配置,统一配置,通过镜像快速启动(Simplifying)
2)代码流水线管理,开发环境->测试环境->预生产环境->灰度发布->正式发布,docker在这里实现了快速迁移(Code Oioeline Management)
3)开发效率,对开发人员,有了镜像,直接启动容器即可(Developer Productivity)
4)应用隔离,相对于虚拟机的完全隔离会占用资源,docker会比较节约资源(App lsolation)
5)服务器整合,一台服务器跑多个docker容器,提高服务器的利用率(Server Consolidation)
6)调试能力,debug调试(Debugging Capabilties)
7)多租户,一个租户多个用户,类似于阿里公有云的一个project下多个用户(Multi-tenancy)
8)快速部署,不需要启动操作系统,实现秒级部署(Rapid Deplovment)
五、安装docker并且pull镜像
yum install -y docker
systemctl start docker
systemctl enable docker
下载镜像(时间较长):
docker pull centos
docker pull registry
docker pull nginx
也可以使用docker导入和导出镜像:
docker load < /opt/centos.tar.gz
docker save centos > /opt/centos.tar.gz
搜索镜像:docker search +镜像名字
查看镜像:docker images
注: 每个镜像都有一个唯一的ID
删除镜像:docker rmi +镜像ID,如果镜像用于创建了容器是不能被删除的,需要先删除容器
六、容器
6.1 启动容器
启动容器:docker run 启动一个容器,centos是镜像的名称,如果没有centos这个镜像会自动pull一个,后面的是command,在这里命令执行完容器也就退出了
[root@docker ~]# docker run centos echo "hehe"
查看容器,-a可以查看所有容器,包含退出的和正在运行的:
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7978584b4ac centos "echo hehe" 28 seconds ago Exited (0) 26 seconds ago berserk_panini
启动一个名字为mydocker,不退出(指定-it)的容器
[root@docker ~]# docker run --name mydocker -it centos /bin/bash
[root@29ce3ee90173 /]# 此时容器的主机名就是容器的ID
补充:
--name: 给容器定义一个名称
-i: 则让容器的标准输入保持打开。
-t: 让Docker分配一个伪终端,并绑定到容器的标准输入上
/bin/bash: 执行一个命令
当利用docker run来创建容器时,Docker在后台运行的标准操作包括:
1)检查本地是否存在指定的镜像,不存在就从公有仓库下载
2)利用镜像创建并启动一个容器
3)分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
4)从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
5)从地址池配置一个ip地址给容器
6)执行用户指定的应用程序
7)执行完毕后容器被终止
这时执行完exit,容器也就退出了,想要启动该容器就要start
[root@docker ~]# docker start 29ce3ee90173
29ce3ee90173
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
29ce3ee90173 centos "/bin/bash" 2 minutes ago Up 58 seconds mydocker
6.2 进入docker容器的几种方式
1)使用attach进入,使用此方法进入的话,多个窗口进入时,显示是同步的;而且exit时,该容器也停了
[root@docker ~]# docker attach 29ce3ee90173
2)使用nsenter进入容器,如果没有此命令,yum安装util-linux包即可,使用此方法exit,容器就不会停掉了,推荐使用此方法!!!
获取docker容器进程的pid:
[root@docker ~]# docker inspect --format "{{.State.Pid}}" 29ce3ee90173
36128
进入容器:
[root@docker ~]# nsenter -t 36128 -u -i -n -p
[root@29ce3ee90173 ~]#
3)docker exec
此方法也不推荐使用
6.3 删除和杀掉正在运行的容器
删除容器
docker rm +容器ID或者名称,删除运行的容器,加上-f参数即可
[root@docker ~]# docker rm c720c8a6a3db
c720c8a6a3db
在容器启动时,使用--rm参数,在容器退出时会自动删除,在自己实验的时候很好用。
[root@docker ~]# docker run --rm centos echo "hello world"
hello world
杀掉正在运行的容器:
[root@docker ~]# docker kill $(docker ps -a -q)
29ce3ee90173
七、Docker的网络和存储
7.1 Docker的4种网络模式
1)host模式
众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
例如,我们在192.168.1.200/24的机器上用host模式启动一个含有web应用的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用192.168.1.200:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
2)container模式
在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
3)none模式
这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
4)bridge模式(默认模式)
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为192.168.1.200/24。
Docker完成以上网络配置的过程大致是这样的:
1)在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
2)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。
[root@docker ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242deee1511 no veth20cb318
virbr0 8000.525400c144f4 yes virbr0-nic
3)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
网络拓扑介绍完后,接着介绍一下bridge模式下容器是如何通信的。
7.2 启动一个nginx容器,默认前台运行nginx -g daemon off
[root@docker ~]# docker run -d -P nginx
查看创建的容器,把虚拟机的32769端口映射成nginx容器的80端口,32768端口映射成443端口
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
622269d81b85 nginx "nginx -g 'daemon off" 3 minutes ago Up 3 minutes 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp amazing_bell
mydocker
通过浏览器访问32769端口:
查看docker的log,命令为:docker logs +容器ID
[root@docker ~]# docker logs 29ce3ee90173
启动容器时指定端口:
[root@docker ~]# docker run -d -p 81:80 nginx
e6cefc4d2937c439c189f85e1ea37b348646a3dfd4bcb20186d613743c5baa41
7.3 docker的存储
docker存储的两种模式
1)数据卷
-v /data 挂载data目录
-v file 挂载一个文件
-v src:dst 指定一个挂载目录,开发常用,挂载物理机代码所在目录,nginx直接使用代码
创建一个centos容器,挂载/data目录,挂载的时候可以指定权限,ro,rw等
[root@docker ~]# docker run -it --name volume-test1 -v /data centos
[root@895a9a4ae975 /]# ls -l /data/
total 0
注:/data对应的物理机的路径
[root@docker ~]# docker inspect 895a9a4ae975 |grep -A 5 "Mounts"
"Mounts": [
{
"Name": "2db8cff65b4fc3242e62c231b59d6533bd56fdce3b6d9074feb2022824ac650c",
"Source": "/var/lib/docker/volumes/2db8cff65b4fc3242e62c231b59d6533bd56fdce3b6d9074feb2022824ac650c/_data",
"Destination": "/data",
"Driver": "local",
注:上面标蓝的地方是物理机所在路径也就是容器对应的/data路径
验证挂载情况:
[root@docker ~]# cd /var/lib/docker/volumes/2db8cff65b4fc3242e62c231b59d6533bd56fdce3b6d9074feb2022824ac650c/_data
[root@docker _data]# touch peng
[root@docker _data]# ls
peng
[root@895a9a4ae975 /]# ls -l /data/ (在容器内查看)
total 0
-rw-r--r-- 1 root root 0 Apr 25 14:50 peng
启动一个容器,挂载物理机/opt目录,挂载的时候可以指定权限ro,rw等
[root@docker ~]# docker run -it -v /opt:/opt centos
[root@3a3eb71c21f7 /]# cd /opt/
[root@3a3eb71c21f7 opt]# ls
index.html nginx ngix.tar.gz rh
[root@docker ~]# ls /opt/ (物理机执行)
index.html nginx ngix.tar.gz rh
2)数据卷容器
启动一个容器挂载/data目录,-d启动就放在后台
[root@docker _data]# docker run -d --name myvolume -v /data centos
e54efa889625686f70c9beb341344b2a5a09d8e3408a1848032e033e5cfd3b3e
启动一个容器,挂载到刚才的容器的/data目录
[root@docker ~]# docker run -it --name myvolume-test --volumes-from myvolume centos
[root@4f430d56682c /]#
在物理机中创建个目录在myvolume-test容器内检查挂载情况
[root@docker ~]# docker ps |grep myvolume
4f430d56682c centos "/bin/bash" About a minute ago Up About a minute myvolume-test1
[root@docker ~]# docker inspect 4f430d56682c|grep -A 5 Mounts
"Mounts": [
{
"Name": "2c2abf5f9db57115741bcce627d15d659e7a4ef079b2092bd0c698950b8fc48a",
"Source": "/var/lib/docker/volumes/2c2abf5f9db57115741bcce627d15d659e7a4ef079b2092bd0c698950b8fc48a/_data",
"Destination": "/data",
"Driver": "local",
[root@docker ~]# cd /var/lib/docker/volumes/2c2abf5f9db57115741bcce627d15d659e7a4ef079b2092bd0c698950b8fc48a/_data
[root@docker _data]# mkdir 123
[root@4f430d56682c /]# ls /data/ -l
total 0
drwxr-xr-x 2 root root 6 Dec 26 05:34 123 (在容器内执行)
八、手动构建镜像
先创建一个centos镜像并yum一个nginx等待做镜像
[root@docker ~]# docker run -it --name mynginx centos
[root@378173b83b16 /]#
[root@378173b83b16 /]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
[root@378173b83b16 /]# yum install -y nginx
更改nginx的配置文件改为前台启动,退出容器:
[root@378173b83b16 ~]# vi /etc/nginx/nginx.conf
daemon off;
[root@378173b83b16 /]# exit
exit
基于刚才创建的容器创建一个docker镜像,版本为V1,peng为用户名,镜像名称为mynginx,镜像来自于id为378173b83b16的容器:
[root@docker ~]# docker commit -m "my nginx" 378173b83b16 peng/mynginx:v1
7f52f9681827c4a6a354ed0fdcdaed25cdd7a86bc50ae81d4a4ebd6d312ccd73
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
peng/mynginx v1 7f52f9681827 27 seconds ago 349.7 MB
docker.io/nginx latest e32087da8ee6 2 weeks ago 182.6 MB
docker.io/centos latest 28e524afdd05 3 weeks ago 196.7 MB
通过上述制作的镜像,启动一个容器,要指定用户名peng和版本,如果不指定版本则默认选择lastest
[root@docker ~]# docker run -it --name nginxv1 peng/mynginx:v1
[root@64f90e96221b /]#
九、使用Dockerfile 创建容器
9.1 dockerfile的四大部分
基础镜像信息
维护者信息
镜像操作指令
容器启动时执行指令
9.2 编写Dockerfile创建容器
[root@docker nginx]# mkdir /opt/dockerfille/nginx -p
[root@docker nginx]# cat index.html
hello,world.
[root@docker nginx]# cat Dockerfile
# This is nginx dockfile
# Verion 1.1.1
# Author peng
FROM centos
MAINTAINER peng@alibaba.com
RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
RUN yum install -y nginx
ADD index.html /usr/share/nginx/html/index.html
RUN echo "daemon off;" >>/etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx"]
使用docker build执行dockerfile构建镜像:
[root@docker nginx]# docker build -t peng/mynginx:v2 /opt/dockerfille/nginx/
查看使用dockerfile创建的镜像,并run一个docker容器
[root@docker nginx]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
peng/mynginx v2 e9b122650b4e 17 seconds ago 366.7 MB
[root@docker nginx]# docker run -d --name nginxv2 -p 800:80 peng/mynginx:v2
0e199dccb749d348225125ff35f0342099bbb248478e1d537719e28c1c4bd46f
浏览器直接查看http://192.168.1.200:800:
十、Docker的Registry私有仓库构建
run一个registry。
[root@docker ~]# docker run -d -p 5000:5000 registry
bf2156a9b00e9f2e49ebbd7b79a26ec196886b4f9cd573b6385786cd1207dd77
[root@docker ~]# curl 192.168.1.200:5000/v1/search
{"num_results": 0, "query": "", "results": []}
给registry打一个新的tag:
[root@docker ~]# docker tag peng/mynginx:v2 192.168.1.200:5000/peng/mynginx:lastest
配置nginx,使用用户认证https的方式将镜像push到仓库中,必须使用https!!
增加一个nginx-registry的配置文件:
[root@docker conf.d]# pwd
/etc/nginx/conf.d
[root@docker conf.d]# cat docker-registry.conf
upstream docker-registry {
server 127.0.0.1:5000;
}
server {
listen 443;
server_name registry.peng.com;
ssl on;
ssl_certificate /etc/ssl/nginx.crt;
ssl_certificate_key /etc/ssl/nginx.key;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 0;
chunked_transfer_encoding on;
location / {
auth_basic "Docker";
auth_basic_user_file /etc/nginx/conf.d/docker-registry.htpasswd;
proxy_pass http://docker-registry;
}
location /_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
location /v1/_ping {
auth_basic off;
proxy_pass http://docker-registry;
}
}
生成一个根证书,生产环境最好是买一个证书:
[root@docker CA]# cd /etc/pki/CA/
[root@docker CA]# touch ./{serial,index.txt}
[root@docker CA]# echo 00 >serial
[root@docker CA]# openssl genrsa -out private/cakey.pem 2048
Generating RSA private key, 2048 bit long modulus
..........................................................................................+++
..........................+++
e is 65537 (0x10001)
[root@docker CA]# openssl req -new -x509 -key private/cakey.pem -days 3650 -out cacert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:peng
Organizational Unit Name (eg, section) []:peng
Common Name (eg, your name or your server's hostname) []:peng-blog.com
Email Address []:admin@peng-blog.com
生成nginx的key和证书:
[root@docker CA]# cd /etc/ssl
[root@docker ssl]# openssl genrsa -out nginx.key 2048
Generating RSA private key, 2048 bit long modulus
.....+++
...........................+++
e is 65537 (0x10001)
[root@docker ssl]# openssl req -new -key nginx.key -out nginx.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:beijing
Locality Name (eg, city) [Default City]:beijing
Organization Name (eg, company) [Default Company Ltd]:peng
Organizational Unit Name (eg, section) []:peng
Common Name (eg, your name or your server's hostname) []:peng-blog.com
Email Address []:admin@peng-blog.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:peng
签发证书:
[root@docker ssl]# openssl ca -in nginx.csr -days 3650 -out nginx.crt
让系统接收签发的证书:
[root@docker ssl]# cat /etc/pki/CA/cacert.pem >> /etc/pki/tls/certs/ca-bundle.crt
创建密码:
[root@docker ssl]# htpasswd -c /etc/nginx/conf.d/docker-registry.htpasswd peng
New password:
Re-type new password:
Adding password for user peng
启动nginx:
[root@docker ssl]# systemctl start nginx
[root@docker nginx]# netstat -lntup|grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 54093/nginx: master
登录认证并push上打tag的lastest的镜像
[root@docker nginx]#docker login -u peng -p 123456 -e admin@peng-blog.com peng-blog.com
[root@docker nginx]#docker push registry.peng.com/peng/mynginx:lastest
浏览器登录:https://192.168.1.200:443会要求用户输入用户名和密码。服务器提示docker。
十一、Namespace资源隔离
Namespace |
系统调用参数 |
隔离内容 |
UTS |
CLONE_NEWUTS |
主机名与域名 |
IPC |
CLONE_NEWIPC |
信号量、消息队列和共享内存 |
PID |
CLONE_NEWPID |
进程编号 |
Network |
CLONE_NEWNET |
网络设备、网格栈、端口等等 |
Mount |
CLONE_NEWNS |
挂载点(文件系统) |
User |
CLONE_NEWUSER |
用户和用户组 |
1)pid namespace
不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同pid。所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。同时由于允许嵌套,因此可以很方便的实现 Docker in Docker。
2)net namespace
有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过net namespace实现的, 每个net namespace有独立的 network devices,IP addresses,,IP routing tables,/proc/net 目录。这样每个container的网络就能隔离开来。docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge: docker0连接在一起。
3)ipc namespace
container中进程交互还是采用linux常见的进程间交互方法(interprocess communication – IPC),包括常见的信号量、消息队列和共享内存。然而同 VM 不同的是,container 的进程间交互实际上还是host上具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息 -- 每个IPC资源有一个唯一的 32 位 ID。
4)mnt namespace
类似chroot,将一个进程放到一个特定的目录执行。mnt namespace允许不同namespace的进程看到的文件结构不同,这样每个 namespace 中的进程所看到的文件目录就被隔离开了。同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在namespace的mount point。
5)uts namespace
UTS(“UNIX Time-sharing System”) namespace允许每个container拥有独立的hostname和domain name, 使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
6)user namespace
每个container可以有不同的 user 和 group id,也就是说可以在container内部用container内部的用户执行程序而非Host上的用户。
十二、docker拓展
12.1 可配额/可度量 – Control Groups (cgroups)
cgroups 实现了对资源的配额和度量。
cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。
groups可以限制blkio、cpu、cpuacct、cpuset、devices、freezer、memory、net_cls、ns九大子系统的资源,以下是每个子系统的详细说明(可以使用docker run -help查看):
blkio 这个子系统设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及usb等等。
cpu 这个子系统使用调度程序为cgroup任务提供cpu的访问。
cpuacct 产生cgroup任务的cpu资源报告。
cpuset 如果是多核心的cpu,这个子系统会为cgroup任务分配单独的cpu和内存。
devices 允许或拒绝cgroup任务对设备的访问。
freezer 暂停和恢复cgroup任务。
memory 设置每个cgroup的内存限制以及产生内存资源报告。
net_cls 标记每个网络包以供cgroup方便使用。
ns 名称空间子系统。
附录:
Docker基础命令
[root@docker ~]# docker –help
Usage:
docker [OPTIONS] COMMAND [arg…]
docker daemon [ –help | … ]
docker [ –help | -v | –version ]
A
self-sufficient runtime for containers.
Options:
–config=~/.docker Location of client config files #客户端配置文件的位置
-D, –debug=false Enable debug mode #启用Debug调试模式
-H, –host=[] Daemon socket(s) to connect to #守护进程的套接字(Socket)连接
-h, –help=false Print usage #打印使用
-l, –log-level=info Set the logging level #设置日志级别
–tls=false Use TLS; implied by–tlsverify
–tlscacert=~/.docker/ca.pem Trust certs signed only by this CA #信任证书签名CA
–tlscert=~/.docker/cert.pem Path to TLS certificate file #TLS证书文件路径
–tlskey=~/.docker/key.pem Path to TLS key file #TLS密钥文件路径
–tlsverify=false Use TLS and verify the remote #使用TLS验证远程
-v, –version=false Print version information and quit #打印版本信息并退出
Commands:
attach Attach to a running container #当前shell下attach连接指定运行镜像
build Build an image from a Dockerfile #通过Dockerfile定制镜像
commit Create a new image from a container’s changes #提交当前容器为新的镜像
cp Copy files/folders from a container to a HOSTDIR or to STDOUT #从容器中拷贝指定文件或者目录到宿主机中
create Create a new container #创建一个新的容器,同run 但不启动容器
diff Inspect changes on a container’s filesystem #查看docker容器变化
events Get real time events from the server #从docker服务获取容器实时事件
exec Run a command in a running container #在已存在的容器上运行命令
export Export a container’s filesystem as a tar archive #导出容器的内容流作为一个tar归档文件(对应import)
history Show the history of an image #展示一个镜像形成历史
images List images #列出系统当前镜像
import Import the contents from a tarball to create a filesystem image #从tar包中的内容创建一个新的文件系统映像(对应export)
info Display system-wide information #显示系统相关信息
inspect Return low-level information on a container or image #查看容器详细信息
kill Kill a running container #kill指定docker容器
load Load an image from a tar archive or STDIN #从一个tar包中加载一个镜像(对应save)
login Register or log in to a Docker registry #注册或者登陆一个docker源服务器
logout Log out from a Docker registry #从当前Docker registry退出
logs Fetch the logs of a container #输出当前容器日志信息
pause Pause all processes within a container #暂停容器
port List port mappings or a specific mapping for the CONTAINER #查看映射端口对应的容器内部源端口
ps List containers #列出容器列表
pull Pull an image or a repository from a registry #从docker镜像源服务器拉取指定镜像或者库镜像
push Push an image or a repository to a registry #推送指定镜像或者库镜像至docker源服务器
rename Rename a container #重命名容器
restart Restart a running container #重启运行的容器
rm Remove one or more containers #移除一个或者多个容器
rmi Remove one or more images #移除一个或多个镜像(无容器使用该镜像才可以删除,否则需要删除相关容器才可以继续或者-f强制删除)
run Run a command in a new container #创建一个新的容器并运行一个命令
save Save an image(s) to a tar archive #保存一个镜像为一个tar包(对应load)
search Search the Docker Hub for images #在docker hub中搜索镜像
start Start one or more stopped containers #启动容器
stats Display a live stream of container(s) resource usage statistics #统计容器使用资源
stop Stop a running container #停止容器
tag Tag an image into a repository #给源中镜像打标签
top Display the running processes of a container #查看容器中运行的进程信息
unpause Unpause all processes within a container #取消暂停容器
version Show the Docker version information #查看容器版本号
wait Block until a container stops, then print its exit code #截取容器停止时的退出状态值
Run ‘docker COMMAND –help’ for more information on a command. #运行docker命令在帮助可以获取更多信息