Docker 学习

283 阅读12分钟

环境 centos7 64

Docker是一个基于轻量级虚拟化技术的容器引擎项目。

三大组件

镜像 Docker images

仓库 Docker registeries

容器 Docker containers

Docker安装

确定yum源是否可用

cd /etc/yum.repos.d/
ls
#清除本地缓存
yum clean all
#查看(开启的)资源库
yum repolist

安装docker

yum install docker -y

远程连接

vim /etc/hosts
#最后一行添加
本机ip docker-server
#连接
ssh-copy-id -i docker-server
ssh docker-server

启动docker

systemctl start docker
docker -v
docker version
#client 与 server ,单独一个没启动成功

使用官方源(下载速度慢)

# 拉取nginx的docker库
# 先查找   -s 100 星级超过100的
docker search nginx -s 100  
# 再拉取
# 镜像名称在查找的name列
docker pull 镜像名称

查看已经下载的docker镜像

docker image list

登录登出Docker Hub(需要注册账号)

docker login
docker logout

使用国内源(网易蜂巢、aliyun和daocloud)/国内的docker加速器

daocloud官网注册 免费
https://hub.daocloud.io/

点击发现镜像 再点击加速器图标
出现命令 复制  执行

#重启docker
systemctl restart docker

重启报错job for docker.service failes becausee the control process exited with error code.

尝试 手动配置加速器
vim /etc/docker/daemon.joon
{
    "registry-mirrors":[
    	"http://18fbeab1.m.daocloud.io"
    ],
    "insecure-registries":[]
}
systemctl restart docker

点击集群管理 管理主机 添加主机 照步骤走
等待连接变成恭喜连接成功
查看主机 显示详细信息


使用daocloud下拉nginx镜像
dao pull nginx
如果有WARNING:IPv4 forwarding is disabled.Networking will not work.警告
执行下面命令,将路由转发打开
echo 1 > /proc/sys/net/ipv4/ip_forward   
dao pull nginx           #下载速度会加快

显示所有镜像列表
docker image list

运行容器  
docker run -it --name="nginx" docker.io/nginx /bin/bash

如何使用这个镜像
方法一 nginx 托管静态网页内容  

-d 以守护进程的方式运行
docker run --name nginx1 -v /html:/usr/share/nginx/html:ro -d daocloud.io/nginx

方法二 暴露端口
docker run --nmae some-nginx -d -p 8080:80 xome-content-nginx
这样启动可以通过http://localhost:8080 或者 http://宿主ip:8080访问nginx了

启动nginx
cd /run/
/etc/init.d/nginx start

安装elinks

yum install elinks -y
查看容器详细信息包括ip
docker inspect 容器的id/容器名
访问镜像ip
elinks --dump  http://docker的ip
如果访问被拒绝。先启动nginx,再关闭防火墙后,重试。

关闭防火墙
systemctl stop firewalld

镜像操作

搜索官方基于Ubuntu操作系统的镜像

docker search ubuntu
搜索星级至少是100的镜像
docker search -s 100 ubuntu

拉取镜像

默认为官方库
docker pull ubuntu

查看已经到渠道本地的镜像

docker images
docker image ls
docker image list

查看所有镜像的id号
docker images -q

删除镜像命令

删除镜像

docker rmi  镜像名
docker rmi  镜像id  --force或者-f
正在运行的不能删,如果非要删除用--force

删除所有镜像

docker rmi $(docker images -q)

删除所有未打tag的镜像

docker rmi $(docker images| awk '/^<none>/ { print $3 }')

根据格式删除所有镜像

删除状态为exited的镜像
docker rm $(docker ps -qf status=exited)
docker rm 镜像id号

容器操作

运行容器

# 依据镜像创建容器但留在主机。如果想要进入容器,使用attach
docker run -tid 镜像id
-i 捕获标准输入输出
-t 分配一个终端或者控制台
-d 后台运行
--name 给容器指定名字
#注意 --name 必须在镜像id之前
docker run -tid --name 名字 镜像id

断开与容器的连接 输入exit

-h 远程连接到某一台机器
docker run -it -h test.up.com daocloud.io/centos:7

docker ps命令

在其他窗口列出正在运行的容器

docker ps

列出所有的容器(包括正在运行的容器和已经退出的容器)

docker ps -a
docker ps --all

查找已运行的docker容器的ID

docker ps -q

查找所有的docker容器的ID

docker ps -a -q

列出最近一次启动的容器

docker ps -l

查看状态为exited的镜像

docker ps -qf status=exited

进入容器

docker exec -it doker的id /bin/bash
docker attach docker的id       #id的前四位

查看更详细的关于某一个容器的信息

inspect Return low-level information on a container or image
用于查看容器的配置信息,包含容器名、环境变量、运行命令、主机配置、网络配置和数据卷配置等

查看容器信息
docker inspect 镜像id(可以使用id的前三个字符,不需要完整的id)

查看容器网关                json数据
docker inspect --format='{{.NetworkSettings.Gateway}}' 容器id

退出容器

exit              #会使容器停止    状态 exited
组合键ctrl p q    #容器不停止      状态 up

连接之前退出的容器(已经启动的容器)

两种方法
docker start 容器id(bb5d)
docker attach 容器id号(bb5d)

docker start 容器id(bb5d)
docker exec -it bb5d /bin/bash
通过exec命令可以创建两种任务:
后台型任务:
-d 运行到后台
docker exec -d elated_lovelace touch 123
交互型任务:
docker exec -it elated_lovelace /bin/bash

容器运行到后台

容器运行到后台  -d 运行到后台
docker run -it -d daocloud.io/library/centos:6 /bin/bash
连接容器
docker attach id

查看容器的运行日志 记录一个容器的所有操作

docker logs 容器id
--tail 指定查看最后几条日志
-t     对日志条目附加时间戳
-f     可以跟踪日志的输出,直到手动停止

显示一个运行的容器里面的进程信息

docker top 容器名/容器ID

创建一个容器但不启用它

使用docker镜像hello-world创建一个容器,并将其命名为wing-s-docker
docker create -it --name 'wing-s-docker' docker.io/hello-world
状态为 Created

启动容器
docker start id

容器间通信连接

docker run -tid  --name h1 镜像名:标签
docker run -tid  --name h2 --link h1 镜像名:标签
尝试是否通信
docker attach h2的id
cat etc/hosts
ping h1的ip

在宿主机和容器之间相互copy文件

# 宿主文件拷贝到容器的根目录下面   id可以不用写全 也可以写docker名字
docker cp  宿主机文件路径  docker的id:/

单个容器使用共享卷

实现共享宿主机的tmp目录  
voltest -v 宿主机的tmp目录:容器的挂载点  
docker run -it --name voltest -v /tmp:/volume daocloud.io/library/centos:6 /bin/bash

共享给多个容器  voltest与上一个共享名相同实现相同的目录共享
docker run -it --name voltest1 --volumes-form voltest  daocloud.io/library/centos:6 /bin/bash

关闭容器

正常关闭容器
docker stop 容器ID
强制终止容器
docker kill 容器ID 

stop 命令给容器中的进程发送SIGTERM信号,默认行为是会导致容器退出,当然,容器内程序可以捕获该信号并自行处理,例如可以选择忽略。
kill 命令则是给容器的进程发送SIGKILL信号,该信号将会使容器必然退出

删除一个或多个处于终止状态的容器

docker rm 容器id/容器名
docker rm 'docker pa -a -q'

如果要删除一个运行中的容器,可以添加-f参数。docker 会发送SIGKILL信号给容器

杀死所有running状态的容器

-q 只显示容器id号
docker kill $(docker ps -q)

查看容器内发生改变的文件

docker diff 容器ID

Clean Up

默认情况下,每个容器在退出时,它的文件系统也会保存下来,这样一方面调试会方便些,因为你可以通过查看日志等方式来确定最终状态。另外一方面,你也可以保存容器所产生的数据。
但是当你仅仅需要短暂的运行一个容器,并且这些数据不需要保存,你可能就希望Docker能在容器结束时自动清理其所产生的数据,这时就要用到-rm这个参数
注意 -rm与-d不能共用
--rm=false: Automatically remove the container when it exits (incompatible with -d)

docker run -it --rm daocloud.io/library/centos:6 /bin/bash

实时输出docker服务器端的事件,包括容器的创建,启动,关闭等

docker events
在另一个docker-server端执行然后docker events会有事件输出
docker start 容器ID/容器名

创建自己的镜像

显示镜像的制作过程,相当于dockfile

docker history 镜像名字:标签

将容器文件系统打包成tar文件

第一种
docker export -o xxxx.tar 容器名/容器id
ls
第二种
docker export 容器名 > xxxx.tar


拷贝到另一台linux上的根目录下
scp xxxx.tar id:/

ssh id

运行docker 
systemctl  start docker 
关闭防火墙
systemctl stop firewalld
docker images  里面什么都没有
导入包 并且给容器起名:tag
docker import  xxx.tar   命名:标签
docker images  显示出现一个容器
docker run -it 容器ID /bin/bash


第二种方法 将镜像打包
查看镜像
docker images
将镜像打包,与load命令相对应
docker save -o xxx.tar 镜像名/镜像ID
将save命令打包的镜像通过load命令导入
docker load < xxx.tar

通过容器创建本地镜像

docker commit -m '镜像描述' -a '作者信息' 现在容器id  镜像名字:标签
docker commit 容器id 镜像名字:标签
docker run -it 镜像名字:标签  bin/bash

通过Dockerfile创建镜像(批量)

创建镜像所在文件夹和Dockerfile文件

mkdir sinatra
cd sinatra
touch Dockerfile

在Dockerfile文件中写入命令,每一条执行都会更新镜像的信息

vim Dockerfile

# this is a comment
FROM ubuntu:14:04
MAINTAINER wing wing@localhost.localdomain
RUN apt-get update && apt-get install -y ruby ruby-dev
RUN gem install sinatra
格式说明:
每行命令都是以 INSTRUCTION statement 形式,就是命令+清单的模式。
命令要大写
FROM 命令告诉docker我们的镜像是什么
MAINTAINER 是描述镜像的创建人
RUN 命令是在镜像内部执行。也就是说后面的命令是针对镜像可以运行的命令
例子:
# this is a comment
FROM daocloud.io/library/centos:6
MAINTAINER wing wing@1000phone.net
RUN useradd jim
RUN echo aaa > a.txt
RUN rm -rf /tmp/*
RUN echo haha > /tmp/b.txt

创建镜像

docker build -t wing:sinatra:v2 .
docker build 是docker创建镜像的命令
-t 是标识新建的镜像属于 ouruser的   
sinatra 是仓库的名称
:v2 是tag
. 是用来指明我们的使用的dockerfile文件当前目录的

创建完成后,从镜像创建容器

docker run -t -i wing/sinatra:v2 /bin/bash

部署私有镜像

下载仓库镜像

docker login daocloud.io || docker loginout
docker pull daocloud.io/library/registry:latest

# -p  创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用,可以用多个-p指定多个端口映射关系
# 使用-p做端口转发,把本地3307转发到容器的3306
# docker run -d --name mysql1 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123

运行镜像
docker run -d -it -p 5000:5000 daocloud.io/library/registry
如果出现iptables:no chaim/target/match by that name
解决方法 
yum install iptables* -y
systemctl start iptables
systemctl stop firewalld
iptables -nL -t nat
**可以不用进行这一步
**重新装docker
**yum reinstall docker
重启docker
systemctl restart docker
docker run -d -it -p 5000:5000 daocloud.io/library/registry /bin/sh
docker exec -it 容器的id /bin/sh
netstat -lnp

进入私有仓库中去

docker exec -it 容器ID /bin/sh    用sh而不是bash 因为这里是没有做软连接的
netstat -lnp 查看5000端口是否开启

在本机查看是否访问该私有仓库,看状态码是不是200

curl -I 127.0.0.1:5000

实验是否能链接

下载个小镜像
docker pull busybox
再上传前需要将镜像做个tag,注明ip与端口
docker tag busybox 本机ip:端口/busybox
docker tag busybox 172.16.113.169:5000/busybox
上传镜像到私有仓库
docker push 172.16.113.169:5000/busybox
如果报错 server gave HTTP response to HTTPS client
解决方法
在/etc/docker目录下创建daemon.json文件,写入
{"insecure-registries":["172.16.113.169:5000"]}
保存并退出,
重启docker
systemctl restart docker
重启容器
docker start 容器id
docker push 172.16.113.169:5000/busybox

查看私有仓库里的所有镜像

curl 172.16.113.169:5000/v2/_catalog

数据卷

创建

#创建名为ferivol的数据卷
docker volume create firvol

查看所有数据卷

docker volume ls

查看指定的数据卷

docker columne inspect firvol

删除数据卷

docker volume rm firvol

再删除容器的同时移除数据卷无主的数据卷可能占用很多空间,可以使用下面命令删除

docker volume prune

挂载主机目录作为数据卷有两种方法 -v --volume 与 --mount两种方式

以下示例将卷myvol2装入 /app/容器中

--mount 方式:

[root@benjamincloud ~]# docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
c7e40bded7d029a9523bd8e0aa145741509c81dff54780adfd4e79aba5d92eb8

使用 -v or  --volume 的方式:

[root@benjamincloud ~]# docker run -d --name devtest -v myvol2:/app nginx:latest
27ecdae2edc59bcd7521ec257913fb70586d49aa014e45240a7c468289ac7849

使用只读卷

[root@benjamincloud ~]# docker run -d --name nginx-test --mount source=nginx-vol,target=/usr/share/nginx/html,readonly nginx:latest
85848e9a91176323ed8ee954c4663bf039889037648b360e374822b71cd0a487

[root@benjamincloud ~]# docker run -d --name nginx-test --volume nginx-vol:/usr/share/nginx/html:ro nginx:latest
9e314ab6058c968c39ae713367dfb87e9ef6bac7706e32168cf40bcb143c2f80

docker 网络

方法一 路由方式

小规模docker环境大部分运行在单台主机上,如果公司大规模采用docker,那么多个宿主机上的docker如何互联
不同宿主机连接在一起
Docker默认内部IP为172.17.42.0网段,所以必须修改其中一台的默认网段以免IP冲突
vim /etc/sysconfig/docker-network
DOCKER_NETWORK_OPTIONS= --bip=172.18.42.1/16
重启系统
reboot


静态路由
docker 130上 
route add -net 172.18.0.0/16 gw 192.168.18.128

docker 128上 
route add -net 172.17.0.0/16 gw 192.168.18.130
现在两台宿主机里的容器就可以通信了

方法二 open vswitch方式

在docker1宿主机和docker2宿主机上分别建立桥接网卡和路由
yum install -y bridge-utils
ovs-vsctl add-br obr0
ovs-vsctl add-port obr0 gre0 -- set interface gre0 type=greoptions:remote_ip=192.168.245.143
remote_ip指本机IP

brctl addbr kbr0

brctl addif kbr0 obr0
ip link set dev docker0 down
ip link del dev docker0

vim /etc/sysconfig/network-scripts/ifcfg-kbr0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.101.10
NETMASK=255.255.255.0
GATEWAY=192.168.101.0
USERCTL=no
TYPE=Bridge
IPV6INT=no
DEVICE=kbr0

设置到达docker2宿主机新建哇昂桥所在网络的路由
vim /etc/sysconfig/network-scripts/route-ens33
192.168.100.0/24 via 192.168.245.155 dev ens33

systemctl restart network

route -n

虚拟网卡绑定kbr0后下载容器启动测试
cat /etc/sysconfig/docker-network
vim /etc/sysconfig/docker-network
DOCKER_NETWORK_OPTIONS="-b=kbr0"

systemctl restart docker

主要使用k8s里面的网络方式