Docker使用

lxc

描述和基本概念

Description : Linux Resource Containers provide process and resource isolation without the
overhead of full virtualization.
lxc:LinuX Container
chroot,根切换;
namespaces:名称空间
CGroups:控制组
Namespace:隔离技术的第一层,确保 Docker 容器内的进程看不到也影响不到 Docker 外部的进程。
Control Groups:LXC 技术的关键组件,用于进行运行时的资源限制。
UnionFS(文件系统):容器的构件块,创建抽象层,从而实现 Docker 的轻量级和运行快速的特性

KVM与LXC几点区别:

  1. KVM是在物理机系统里面进行了虚拟化,虚拟机里面有自己的系统和文件系统,应用通过调用虚拟机系统内核接口,然后调用物理机内核接口,使用物理资源,LXC直接排除了虚拟机系统,直接在物理机上创建文件系统,并直接调用物理机内核接口,使用物理资源。

docker是lxc的管理器,lxc是cgroup的管理工具,cgroup是namespace的用户空间的管理接口。namespace是linux内核在task_struct中对进程组管理的基础机制

其中CGroup的含义包含一下几个概念
(1)任务(task):在 cgroups 中,任务就是系统的一个进程。

(2)控制族群(control group):控制族群就是一组按照某种资源限制划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到多个控制族群。假设这里有个进程A,我们要限制其使用的系统内存总量的10%,我们就可以创建一个memory占用10%的cgroups。然后,将进程A添加到cgroups,那么进程A最多占用内存总量的10%,当然,一个cgroups一般情况下不止一个进程。

(3)层级(hierarchy):控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。子控制组自动继承父节点的特定属性,当然子控制组还可以有自己特定的属性。

参考:https://blog.csdn.net/henweimei/article/details/52127684
https://blog.csdn.net/u014242496/article/details/72781295

namespace
命名空间在我看来,跟作用域差不多,每个命名空间相当于一个单独的个体,

  • 每个 namespace 中的 pid 是有自己的 pid=1 的进程(类似 /sbin/init 进程)
  • 每个 namespace 中的进程只能影响自己的同一个 namespace 或子 namespace 中的进程
  • 因为 /proc 包含正在运行的进程,因此在 container 中的 pseudo-filesystem 的 /proc 目录只能看到自己 namespace 中的进程
  • 因为 namespace 允许嵌套,父 namespace 可以影响子 namespace 的进程,所以子 namespace 的进程可以在父 namespace 中看到,但是具有不同的 pid

CGroup是控制cpu、memory等资源的
namespace是做隔离的,包括

  • mnt(每个 namespace 中的进程所看到的文件目录就被隔离开了,类似chroot)
  • net namespace(每个 container 的网络就能隔离开)
  • uts namespace(允许每个 container 拥有独立的 hostname 和 domain name)
  • ipc namespace ()
  • user namespace (可以有不同的 user 和 group id)

![lxc][1]

基础命令

简单使用:
lxc-checkconfig:
检查系统环境是否满足容器使用要求;
lxc-create:创建lxc容器;
lxc-create -n NAME -t TEMPLATE_NAME
lxc-start:启动容器;
lxc-start -n NAME -d
lxc-info:查看容器相关的信息;
lxc-info -n NAME
lxc-console:附加至指定容器的控制台;
lxc-console -n NAME -t NUMBER
lxc-stop:停止容器;
lxc-destory:删除处于停机状态的容器;

	lxc-snapshot:创建和恢复快照;

docker

基本命令

物理:
Client <--> Daemon <--> Registry Server
逻辑:
Containers:容器
Images:镜像、映像
Registry:Image Repositories

容器的状态:
	created:
	runing:
	paused:
	stopped:
	deleted:
	
docker 
	images
	pull
	run
	ps
	
查看docker相关的信息:
	version
	info
	
镜像:
	images
	rmi
	pull
	
容器:
	run:创建并运行一个容器;
	create:创建一个容器;
	start:启动一个处于停止状态容器;
	
	创建:
		create
		run 
		
	启动:
		start
		
	停止:
		kill
		stop
		
	重启:
		restart
		
	暂停和继续:
		pause
		unpause 
		
	删除容器:
		rm
		run --rm

docker run 命令

-a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;

-d: 后台运行容器,并返回容器ID;

-i: 以交互模式运行容器,通常与 -t 同时使用;

-p: 端口映射,格式为:主机(宿主)端口:容器端口

-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

--name="nginx-lb": 为容器指定一个名称;

--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;

--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;

-h "mars": 指定容器的hostname;

-e username="ritchie": 设置环境变量;

--env-file=[]: 从指定文件读入环境变量;

--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;

-m :设置容器使用内存最大值;

--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;

--link=[]: 添加链接到另一个容器;

--expose=[]: 开放一个端口或一组端口
-v: 目录映射  主机目录:容器目录

docker基本命令使用

# 安装docker
yum install docker
# 启动docker程序
service docker start
systemctl start docker
# 查看包的内容
rpm -ql docker
# 查看docker信息
docker info
# 拉取docker镜像
docker pull busybox
# 查询网络镜像
docker search centos
# 查询本地镜像
docker images
# 运行centos镜像
docker run -it centos
-it  直接进入bash界面
-d   进入后台
centos镜像无法进入后台,只能直接进入bash,nginx镜像可以后台进行
--hostname HOSTNAME 给容器指定主机名
--dns DNS_SERVER_IP 给容器指定DNS服务器地址
--add-host HOSTNAME:IP  给容器添加指定本地主机名解析,就是修改/etc/hosts文件
# 运行nginx镜像 指定端口 --rm 是当容器关闭时自动删除

docker run --name mynginx -it -d -p 127.0.0.1:80:8080  -v /data/logs/nginx:/var/log/nginx/ nginx:latest 
## nginx容器内没法使用vi、yum命令,所以要将相关目录映射到宿主机上面,如何对已经运行的容器添加目录映射
参考https://blog.csdn.net/pushiqiang/article/details/79539423

## 如何将容器中的文件拷贝到宿主机当中

docker cp命令


# 查询所有容器(包括已经删除的)
docker ps -a
-a :显示所有的容器,包括未运行的。

-f :根据条件过滤显示的内容。

--format :指定返回值的模板文件。

-l :显示最近创建的容器。

-n :列出最近创建的n个容器。

--no-trunc :不截断输出。

-q :静默模式,只显示容器编号。

-s :显示总的文件大小。
# 进入一个已存在的容器
docker attach ID  进入之后,执行exit会导致容器stop
docker exec -it ID /bin/bash 进入之后,执行exit不会导致容器stop(推荐)
#启动、停止、重启容器
docker start ID
docker stop ID
docker restart ID
#直接应用kill杀掉容器
docker kill -s 9 ID

#删除容器
docker rm -f ID (docker ps -a 无法查询到,完全删除)
docker rm -l 连接名 (-l :移除容器间的网络连接,而非容器本身)
docker rm -v ID 删除容器nginx01,并删除容器挂载的数据卷,需要先stop掉容器(仅对默认卷有效?对-v命令映射的卷无效)

# 暂定和取消暂定容器
docker pause ID
docker unpause ID
# 创建一个容器但是不启动
docker create --name mynginx  -p 127.0.0.1:80:8080  -v /data/logs/nginx:/var/log/nginx/ nginx:latest 
# 在容器中执行命令
docker exec -it ID /bin/bash 
docker exec -it ID cat /etc/passwd
-d :分离模式: 在后台运行

-i :即使没有附加也保持STDIN 打开

-t :分配一个伪终端

# 获取容器的元数据
docker inspect mynginx
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mymysql

# 查看容器中运行的进程信息
docker top ID
for i in  `docker ps |grep Up|awk '{print $1}'`;do echo \ &&docker top $i; done
#从容器中获取实时事件
docker events -f "image"="mysql:5.6" --since="1467302400" 
-f :根据条件过滤事件;

--since :从指定的时间戳后显示所有事件;

--until :流水时间显示到指定的时间为止;

#获取容器日志
docker logs mynginx
-f : 跟踪日志输出

--since :显示某个开始时间的所有日志

-t : 显示时间戳

--tail :仅列出最新N条容器日志

# 将文件系统作为一个tar归档文件导出到STDOUT
docker export -o nginx-`date +%F`.tar mynginx

#从tarball中导入一个文件系统镜像,生成镜像
docker import /tmp/nginx-2019-05-06.tar myngninx:v1.0 
然后进行运行容器时,要写COMMAND,且如果有映射需要注意映射的卷不能打包
docker run -it --name mynginx1.0 -d -v /data/logs/mynginx1.0:/var/log/nginx/ mynginx:v1.0 nginx -g 'daemon off;' 
nginx -g 'daemon off;' 是通过docker ps查询或者docker inspect查询
#查询端口映射关系
docker port mynginx

容器rootfs命令

# 从容器创建一个新的镜像
docker commit -a "runoob.com" -m "my apache" a404c6c174a2  mymysql:v1 
-a :提交的镜像作者;

-c :使用Dockerfile指令来创建镜像;

-m :提交时的说明文字;

-p :在commit时,将容器暂停。

# 用于容器与主机之间的数据拷贝
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
-L :保持源目标中的链接
docker cp /tmp/www mynginx:/tmp/ -L

#查看容器mymysql的文件结构更改,就是看看容器里面跟images有啥区别
docker diff ID

镜像仓库

#仓库登录
docker login : 登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub

docker logout : 登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub
docker login -u albertyxy 

#从镜像仓库中拉取或者更新指定镜像
docker pull java
docker pull docker.io/albertyxy/nginx:v1.0.2
#推送本地镜像到我自己的镜像库albertyxy
1. 先登录
2. 要在本地先生成镜像,利用docker tag 
docker tag mynginx:v2.0 albertyxy/nginx:v2.0
docker push albertyxy/nginx:v2.0

# 从Docker Hub查找镜像
docker searce nginx

本地镜像管理

#docker images [OPTIONS] [REPOSITORY[:TAG]] 列出本地镜像
-a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);

--digests :显示镜像的摘要信息;

-f :显示满足条件的镜像;

--format :指定返回值的模板文件;

--no-trunc :显示完整的镜像信息;

-q :只显示镜像ID。

# 删除本地一个或多少镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
-f :强制删除;
--no-prune :不移除该镜像的过程镜像,默认移除;

# 标记本地镜像,将其归入某一仓库
docker tag mynginx:v2.0 albertyxy/nginx:1.0.1

# docker build 命令用于使用 Dockerfile 创建镜像(限制资源也可以在使用docker run命令的时候指定)
docker build [OPTIONS] PATH | URL | -
--build-arg=[] :设置镜像创建时的变量;

--cpu-shares :设置 cpu 使用权重;

--cpu-period :限制 CPU CFS周期;

--cpu-quota :限制 CPU CFS配额;

--cpuset-cpus :指定使用的CPU id;

--cpuset-mems :指定使用的内存 id;

--disable-content-trust :忽略校验,默认开启;

-f :指定要使用的Dockerfile路径;

--force-rm :设置镜像过程中删除中间容器;

--isolation :使用容器隔离技术;

--label=[] :设置镜像使用的元数据;

-m :设置内存最大值;

--memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap;

--no-cache :创建镜像的过程不使用缓存;

--pull :尝试去更新镜像的新版本;

--quiet, -q :安静模式,成功后只输出镜像 ID;

--rm :设置镜像成功后删除中间容器;

--shm-size :设置/dev/shm的大小,默认值是64M;

--ulimit :Ulimit配置。

--tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。

--network: 默认 default。在构建期间设置RUN指令的网络模式

#查看指定镜像的创建历史
docker history mynginx:v1.0

#将指定镜像保存成 tar 归档文件(跟export类似,只不过这个是镜像,export是容器)
docker save -o 文件名 [OPTIONS] IMAGE [IMAGE...]

# 导入使用 docker save 命令导出的镜像
docker load -i ubuntu.tar
docker load < ubuntu.tar

info |version

#docker info显示 Docker 系统信息,包括镜像和容器数
# 显示 Docker 版本信息
docker version

registry配置

#默认注册表为docker.io 如果想修改,可以在/etc/sysconfig/docker 文件中添加
ADD_REGISTRY='--add-registry registry.access.redhat.com --add-registry docker.io/albertyxy/nginx'
# 如果想放置用户从docker registry中拉取镜像,可以取消如下注释
# 通常情况拉取镜像都是用https,如果没有设置安全证书,那么可以这样
INSECURE_REGISTRY='--insecure-registry newregistry.example.com'

Docker Data Volume

共享volume

#多个容器的卷使用同一个主机目录
docker run -it --name nginx1 -v /data/log/nginx:/var/log/nginx nginx:latest
docker run -it --name nginx2 -v /data/log/nginx:/var/log/nginx nginx:latest
#复制使用其他容器的卷,为docker run 命令使用--volumes-from
docker run -it --name bbox1 -v /data/volumes/v1:/data busybox
docker run -it --name bbox2 --volumes-from bbox1 busybox
# 删除卷
docker volume rm VolumeID

Docker NetWorking

Docker网络分为单主机虚拟网络,多主机网络
其中单主机虚拟网络提供容器隔离
多主机网络

docker network ls

容器类型:

closed containers

不参与网络通信,运行于此类容器中的进程仅能访问本地环回接口
命令:docker run --rm --net none busybox:latest ifconfig -a

Bridged containers

桥接式容器一般拥有两个接口:一个环回接口和一个连接至主机上某桥设备的以太网接口
命令
docker run --rm --net bridge busybox:latest ifconfig -a
Opening inbound communication
NAT桥容器
可以把容器想象成宿主机NAT服务背后的主机,如果开放容器或在容器上服务可以被外部访问,需要在宿主机上为其定义DNAT规则

iptables -t nat -A PREROUTING -d 主机ip -j DNAT --to-destination 容器IP
iptables -t nat -A PREROUTING -d 主机ip -p tcp --dport 80 -j DNAT --to-destination 容器IP:容器端口

-P 选项将容器计划要暴露的端口全部映射到主机端口
--expose 计划要暴露的端口
docker run -d -P --expose 2222 --expose 3333 --name web busybox:latest /bin/httpd -p 2222 -f

Joined contained

联盟式容器:是指某个已存在容器的网络接口的容器,接口被联盟内的各容器共享使用,联盟式容器彼此间完全无隔离

docker run -it -d --rm -p 2222 busybox:latest /bin/httpd -p 2222 -f 
#创建一个联盟 式容器,并查看其监听端口
docker run -it --rm --net container:web --name joined busybox:latest netstat -tan

(有点像负载均衡?)

Open containers

开放式容器共享主机网络名称空间的容器,他们对主机的网络名称空间拥有全部的访问权限,包括访问那些关键性服务,这对宿主机安全性有很大的潜在威胁
docker run -it --rm --net host busybox:latest /bin/sh

DockerFile

DockerFile 主要用于构建镜像
主要语法:
FROM centos:latest as b1 指定基准镜像,as 指定一个别名,配合COPY用
COPY --from=b1 /usr/local /usr/local
默认情况先从本地镜像库拉取镜像,如果没有,会从docker hub中拉取,不过生产环境可以要用自己的镜像源
MAINTAINER
COPY 用于从docker主机复制文件至创建的新印象文件
COPY
注意点:

  1. 必须是build上下文中的路径,不能是其父目录中的文件
  2. 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
  3. 如果指定了多了src,或在中使用了通配符,则必须是一个目录,且必须以/结尾
  4. 如果事先不存在,他将会被自动创建
    ADD
    注意点:
  5. 如果为URL且不以/结尾,则指定的文件将被下载并直接被创建为;如果以/结尾,则文件会放到改目录下,并保存为/
  6. 是tar包,则会将tar包解压成目录保存在指定位置

WORKDIR
用于为Dockerfile 中的所有RUN、CMD、ENTRYPOINT、COPY和ADD指定工作目录

VOLUME ["Mounts",""]
用于在image中创建一个挂载点目录,以挂载Docker host 上的卷或其他r容器上的卷,volume指令不能像-v那样可以指定主机目录,

EXPOSE 8080/tcp 161/utp
端口映射,但是跟VOLUME,不能指定主机端口,随机的

ENV
ENV =
用于镜像定义所需的环境变量
调用格式 $variable_name

RUN command
RUN ["/bin/bash","-c","<executable>","<param1>"]
用于指定docker build过程中运行的程序,其可以是任何命令

CMD
与RUN格式相同,但时间点不同,RUN是运行在构建镜像过程中
CMD是创建容器的时候
CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖
在Dockerfile中可以有多个CMD命令,但仅最后一个生效
CMD command
CMD ["<executable>","<param1>"]
CMD ["<param1>","<param2>"]
第三种格式主要为ENTRYPOINT指令提供默认参数

ENTRYPOINT
ENTRYPOINT command
ENTRYPOINT ["",""]
类似CMD命令,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
docker run 命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后作为其参数使用

USER |
用于指定运行image时或运行Dockerfile中任何RUN、CMD指令指定的程序时用户名或UID
比较重要,生产环境很难用root去执行

ONBUILD
用于在Dokcerfile中定义一个触发器
只在被别人构建时才会触发

Docker 资源配置

--cpu -m --device --ipc --privileged

Docker private registry

yum install docker-distribution -y

# 查看包文件内容
[root@133host ~]# rpm -ql docker-distribution
/etc/docker-distribution/registry/config.yml
/usr/bin/registry
/usr/lib/systemd/system/docker-distribution.service
/usr/share/doc/docker-distribution-2.6.2
/usr/share/doc/docker-distribution-2.6.2/AUTHORS
/usr/share/doc/docker-distribution-2.6.2/CONTRIBUTING.md
/usr/share/doc/docker-distribution-2.6.2/LICENSE
/usr/share/doc/docker-distribution-2.6.2/MAINTAINERS
/usr/share/doc/docker-distribution-2.6.2/README.md
/var/lib/registry

搜索,下载register镜像

docker search registry
docker pull registry
docker images

创建容器registry

mkdir -p /www/docker/registry
docker run --name registry --restart=always -p 5000:5000
-v /www/docker/registry:/var/lib/registry -d registry
docker ps -l

镜像仓库地址使用域名

echo '127.0.0.1 hub.test.com'>>/etc/hosts

修改tag (以hello-world为例)

docker push hello-world
docker tag hello-world hub.test.com:5000/hello-world:1.0

上传、删除、再下载镜像,删除后能下载成功

docker images
docker push hub.test.com:5000/hello-world:1.0
docker rmi hub.test.com:5000/hello-world:1.0
docker images
docker pull hub.test.com:5000/hello-world:1.0
docker images

查看仓库镜像

curl hub.test.com:5000/v2/_catalog

案例

案例0.1:CGroup的使用
```
1.查看cgroup子系统
lssubsys --all
2.查看cgroup子系统的层级路径
lssubsys -m
3.建立一个CPU控制族群
cd /sys/fs/cgroup/cpu
- 创建一个文件夹,即新建一个cpu控制族群:cg1
mkdir cg1
#cpu.cfs_period_us和cpu.cfs_quota_us两个文件。

cpu.cfs_period_us:cpu分配的周期(微秒),默认为100000。

cpu.cfs_quota_us:表示该control group限制占用的时间(微秒),默认为-1,表示不限制。如果设为50000,表示占用50000/10000=50%的CPU。

这里我们测试cpu占用30%,即设置cpu.cfs_quota_us 为30000

    4. 编写测试程序
    vi cpu.sh
    #!/bin/bash
    counter=0
    while [ true ] 
    do
        counter=$counter+1
    done
    5. 执行该脚本
    chmod +x cpu.sh
    ./cpu.sh
    6.用top命令查看cpu达到100%
    7.将该进程放到新建的cg1中,echo 3215 > /sys/fs/cgroup/cpu/cg1/tasks
    再次查看,cpu在30%左右

案例1:采用dockerio镜像源进行安装nginx

查看本地镜像源

docker images

安装docker镜像

docker pull nginx

运行nginx

docker run -it -d --name nginx001 -p 8002:80 -v /data/log/nginx:/var/log/nginx nginx:latest

查看运行情况

curl http://localhost:8002/index.html

案例2:自定义自己的php-fpm镜像

编写Dockerfile

FROM centos:6.8
WORKDIR /usr/local/
ADD . /usr/local/
RUN ln -s /usr/local/php-5.6.30 /usr/local/php
EXPOSE 80

将php-5.6.30安装目录拷贝到Dockerfile目录

执行docker build命令

docker build -t php-5.6.30:v1.0 .

案例3:部署自己的镜像源

安装软件

yum install docker-distribution -y

启动服务

systemctl start docker-distribution

上传镜像

将服务器地址做成域名解析

docker tag php-5.6.30:v2.0 registry.game.360.cn:5000/php-5.6.30:v2.0
docker push registry.game.360.cn:5000/php-5.6.30:v2.0


案例4:对centos6.8系统进行调优
################################
案例5:使用docker hub
################################
案例6:如何限制容器对资源的使用(CPU\MEM\磁盘IO\网络)

6.1 使用-c 命令 默认-c是1024 ,容器按比例使用host cpu资源
docker run -it -d -c 512 --name=nginx1 nginx
docker run -it -d -c 1024 --name=nginx2 nginx
nginx2:nginx1 cpu使用占比 2:1
6.2 限制cpu核数 --cpuset
docker run -it -cpus 1 centos
6.3 限制内存
docker run -it -m 512M centos

案例7:如何修改已经做了端口映射的容器 -p命令
参考
https://www.cnblogs.com/shijf/p/10386193.html


容器自启动策略
docker run --restart string
Flag	Description
no	不自动重启容器. (默认value)
on-failure 	容器发生error而退出(容器退出状态不为0)重启容器
unless-stopped 	在容器已经stop掉或Docker stoped/restarted的时候才重启容器
always 	在容器已经stop掉或Docker stoped/restarted的时候才重启容器

一般选择unless-stopped即可

案例8:如何利用docker daemon 命令修改docker0桥接口网络属性
利用-b --bip --fixed-cidr --default-gateway --dns --mtu
##############################
docker network 
https://www.jianshu.com/p/0a03b68023e1




















  [1]: ./images/1.jpg "1.jpg"
posted @ 2019-05-16 18:32  小翼君  阅读(319)  评论(0编辑  收藏  举报