1.理论:
Docker | VM机 | |
操作系统 | 共享宿主OS | 虚拟OS |
大小 | 镜像小,便于传输 | 大 |
性能 | 准无损耗 | OS损耗机器性能 |
移植性 | 与宿主同OS,轻便,灵活 | 可以不同OS |
速度 | 快 | 慢 |
2.理论:
镜像:打好包的程序,程序环境。
容器:运行镜像的空间,容器外隔离。
仓库:存放镜像的空间,只是存储。
3.理论:
docker:是个软件,本质是宿主机的进程。
LXC:Linux Container,docker底层,提供虚拟化技术。
namespace:实现资源隔离。
cgroup:实现资源限制。
4.Docker安装:
yum源下载。
官网源
# wget https://download.docker.com/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
清华源
# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# yum clean all
# yum install docker-ce -y
# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
改
ExecStart=/usr/bin/dockerd
# systemctl daemon-reload
# systemctl start docker
# systemctl enable docker
# systemctl status docker
# docker -v
我遇到了一次签名问题。
5.镜像的获取
搜索仓库里的镜像
# docker search 关键词
# docker search busybox (例)
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
busybox Busybox base image. 1756 [OK]
progrium/busybox 71 [OK]
拉取镜像
# docker pull 上面的NAME
# docker pull progrium/busybox (例)
搜索本地镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest 6d5fcfe5ff17 6 days ago 1.22MB
删除本地镜像
# docker rmi REPOSITORY名字
# docker rmi IMAGE_ID号码
镜像加速器
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://42h8kzrh.mirror.aliyuncs.com"]
}
# systemctl daemon-reload
# systemctl stop docker
注:得等一会执行start,为什么不直接restart,因为stop的很慢,restart容易还没stop就start,报错。
# systemctl start docker
# systemctl status docker
6.镜像导出导入
导出
# docker save 镜像名 -o /路径/文件名
导入
# docker load < /路径/文件名
7.容器使用镜像
容器执行一个镜像
# docker run --name=别名 镜像名
# docker run -itd --name=别名 镜像名
t=tty终端 d=后台执行 镜像需要带有/bin/bash功能的镜像
查看容器全列表
# docker ps -a
查看容器正运行的列表
# docker ps
查看容器运行结果
# docker logs [CONTAINER_ID]
# docker logs [别名]
启动容器
# docker start [CONTAINER_ID]
# docker start [别名]
停止容器
# docker stop [CONTAINER_ID]
# docker stop [别名]
# docker stop $(docker ps -aq)
查看容器的相关信息
# docker inspect [CONTAINER_ID]
# docker inspect [别名]
如果容器在后台运行,想进入容器操作。
# docker exec [-it] [CONTAINER_ID] [命令]
# docker exec [-it] [别名] [命令]
例如
# docker exec centos ls -l /root/123
# docker exec -it centos /bin/bash
将容器制作自己的镜像
# docker commit [别名] 镜像名
# docker commit [CONTAINER_ID] 镜像名
验证
# docker images
删除容器(先停后删)
# docker rm [别名]
# docker rm [CONTAINER_ID]
删除所有停止的容器(慎用)
# docker system prune
小结:
* docker ps -a : 列出本地的所有容器信息
* docker run 参数选项 --name 容器名 镜像名:TAG 传给容器内部执行的命令
* docker logs 容器名或容器ID: 输出容器内执行命令的结果
* docker stop 容器名或容器ID: 停止容器
* docker start 容器名或容器ID: 启动容器
* docker exec 容器名或容器ID 命令: 不用连接容器,可以外部传命令给容器内部操作
* docker inspect 容器名或容器ID: 查看容器的属性
* docker rm 容器名或容器ID: 删除容器
* docker commit 容器名或容器ID 新的镜像名:TAG 将容器提交为一个镜像
8.仓库
三种:官方仓库,三方仓库,私有仓库
官方仓库:
docker官方仓库
https://hub.docker.com/
注册帐号,新建仓库名,有点像github
# docker login
登陆docker_hub帐号
Username: 略
Password: 略
Login Succeeded
甭管什么仓库,下载pull,上传push,传之前先打标签
# docker push centos:latest
Error response from daemon: You cannot push a "root" repository. Please rename your repository to docker.io/<user>/<repo> (ex: docker.io/<user>/centos)
# docker tag 镜像名:TAG名 帐号名/仓库名:自定义名
# docker push 帐号名/仓库名:自定义名
# docker pull search出的名字(同前文)
官网对这段命令有提示。
退出官网
# docker logout
阿里云仓库:
登陆阿里云,搜索容器镜像服务
以下来源阿里云 》容器镜像服务 》操作指南
1. 登录阿里云Docker Registry
$ sudo docker login --username=用户名 registry.cn-beijing.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
您可以在访问凭证页面修改凭证密码。
2. 从Registry中拉取镜像
$ sudo docker pull registry.cn-beijing.aliyuncs.com/用户名/yuzt_test:[镜像版本号]
3. 将镜像推送到Registry
$ sudo docker login --username=name registry.cn-beijing.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/name/yuzt_test:[镜像版本号]
$ sudo docker push registry.cn-beijing.aliyuncs.com/name/yuzt_test:[镜像版本号]
请根据实际镜像信息替换示例中的[ImageId]和[镜像版本号]参数。
4. 选择合适的镜像仓库地址
从ECS推送镜像时,可以选择使用镜像仓库内网地址。推送速度将得到提升并且将不会损耗您的公网流量。
如果您使用的机器位于VPC网络,请使用 registry-vpc.cn-beijing.aliyuncs.com 作为Registry的域名登录,并作为镜像命名空间前缀。
5. 示例
使用"docker tag"命令重命名镜像,并将它通过专有网络地址推送至Registry。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
registry.aliyuncs.com/acs/agent 0.7-dfb6816 37bb9c63c8b2 7 days ago 37.89 MB
$ sudo docker tag 37bb9c63c8b2 registry-vpc.cn-beijing.aliyuncs.com/acs/agent:0.7-dfb6816
使用"docker images"命令找到镜像,将该镜像名称中的域名部分变更为Registry专有网络地址。
$ sudo docker push registry-vpc.cn-beijing.aliyuncs.com/acs/agent:0.7-dfb6816
通过harbor搭建自己的企业级镜像仓库:
新弄一台机器!!
1.安装docker
# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# yum install epel-release -y
# yum install docker-ce python-devel python2-pip -y
下载docker-compose
# pip install docker-compose -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
或者:
# curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` > /usr/bin/docker-compose
# chmod +x /usr/bin/docker-compose
# systemctl start docker
# systemctl enable docker
2.安装harbor
官网下载地址: http://harbor.orientsoft.cn/
# cd /software
# wget http://harbor.orientsoft.cn/harbor-v1.5.0/harbor-offline-installer-v1.5.0.tgz
# tar xf harbor-offline-installer-v1.5.0.tgz -C /usr/local/
# vim /usr/local/harbor/harbor.cfg
hostname = 192.168.122.18 #将hostname改成harbor服务器的IP
harbor_admin_password = 123 #这是admin用户的默认密码,我这里就不改了
3.重要!
先确保docker-compose文件在/usr/local/bin/里
再执行
# /usr/local/harbor/install.sh
4.docker服务端操作
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://42h8kzrh.mirror.aliyuncs.com"], #注意逗号
"insecure-registries": ["192.168.122.18"] #此处填的是harbor的IP,为了访问用
}
浏览器访问harborIP,进行web管理
仓库搭建好了,docker服务端登陆(不加IP是官方登陆)
# docker login 192.168.122.18
Username: admin
Password: 123
Login Succeeded
退出
# docker logout 192.168.122.18
上传,先打标签
# docker tag hello-world harbor服务IP/仓库名/镜像名:版本号(任意字母数字字符串)
# docker tag hello-world 192.168.122.18/test/hello-world:v1
# docker push harbor服务IP/仓库名/镜像名:版本号(任意字母数字字符串)
# docker push 192.168.122.18/test/hello-world:v1
下载
# docker pull harbor服务IP/仓库名/镜像名:版本号(任意字母数字字符串)
# docker pull 192.168.122.18/test/hello-world:v1
9.容器跑应用
端口映射设置:如果容器中的应用需要访问端口,则将容器的端口与主机的端口绑定,通过访问主机的端口来访问容器的端口。
先打开ip_forward,才能映射成功。
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
# sysctl -p
# docker run --help
用法: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-p, --publish list 映射端口 Publish a container's port(s) to the host
-v, --volume list 挂载文件 Bind mount a volume
-e, --env list 设置环境变量 Set environment variables
-i, --interactive 交互模式 Keep STDIN open even if not attached
-t, --tty 使用tty端口 Allocate a pseudo-TTY
-d, --detach 后台执行 Run container in background and print container ID
--restart=always Docker 重启时,容器自动启动。
例如:
# docker run -d -p 3306:3306 --name=mariadb1 -v /data/mysql:/var/lib/mysql --restart=always -e MYSQL_ROOT_PASSWORD=123 mariadb:latest
诸如
nginx
mysql
httpd等应用,执行后,其实都执行了一个centos,可以-itd开启,然后exec进入它内部操作。
10.Dockerfile
这是啥:可以构建自定义镜像
注:这玩意最后得到的是个镜像,还需要使用docker run执行它。
# vim dockerfile
#镜像名字,必填
FROM centos
#作者名字,选填
MAINTAINER YUZT
#定义环境变量,代替带内部执行
ENV JAVA_HOME=/usr/local/jdk1.8.0_191
#上船文件,URL,或本地文件,重要
ADD local.repo /etc/yum.repos.d/local.repo
#开放端口,无所谓,带有端口的应用会自动打开一个端口
EXPOSE 80
#目录挂载,建议在docker run时执行-v
VOLUME 挂载文件夹
#使用用户UID或名,选填
USER
#WORKDIR 略
#运行shell命令,重点,可以执行一系列linux命令,或一个.sh那么多的命令串,写一起最好
RUN
#开机后执行语句,负责开机启动应用
ENTRYPOINT
或
CMD
保存
构建(注意最后的点!!!!!)
# docker build -f dockerfile_httpd2 -t my_httpd:v2 .
但是我不喜欢这种方式,我还是喜欢打开一个镜像,进去配好再commit成镜像。
11.docker文件的存储(驱动?类型?模式?)
事实:我们已经知道运行一个容器,需要提供一个镜像,多个容器可以共享同一个镜像。
那么,这个共享的过程。。。
docker使用了写时复制cow(copy-on-write)和用时分配(allocate-on-demand)技术来提高存储的利用率。
写时复制:读的时候,未修改数据读取镜像,已修改数据读自己。写的时候,先从镜像复制要写的文件,再修改。
用时分配:当有新文件写入时,才按需分配新空间
常用存储驱动对比
存储驱动 | 特点 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
AUFS | 联合文件系统、未并入内核主线、文件级存储 | 作为docker的第一个存储驱动,已经有很长的历史,比较稳定,且在大量的生产中实践过,有较强的社区支持 | 有多层,在做写时复制操作时,如果文件比较大且存在比较低的层,可能会慢一些 | 大并发但少IO的场景 |
overlayFS | 联合文件系统、并入内核主线、文件级存储 | 只有两层 | 不管修改的内容大小都会复制整个文件,对大文件进行修改显示要比小文件消耗更多的时间 | 大并发但少IO的场景 |
Devicemapper | 并入内核主线、块级存储 | 块级无论是大文件还是小文件都只复制需要修改的块,并不是整个文件 | 不支持共享存储,当有多个容器读同一个文件时,需要生成多个复本,在很多容器启停的情况下可能会导致磁盘溢出 | 适合io密集的场景 |
12.docker网络
如果,两个docker网络之中的容器应用需要相互访问,如何解决跨网段访问??
理论:docker中4种网络类型
1.bridge(默认):不类似桥接,类似NAT,由物理机网卡中转进行上网
2.host:与物理机共享网络,甚至iP地址。
3.none:无网络
4.container:容器间互通,物理机不通。
用bridge百利无害!!!
查看当前docker网络列表。
# docker network ls
新建一个网络IP段
# docker network create -d 模式名 --subnet "网段/掩码" --gateway "网关" 网名
# docker network create -d bridge --subnet "10.3.3.0/24" --gateway "10.3.3.1" bridge0
使用特定的网络IP段
# docker run -itd --name 容器名 --network 网名 镜像:版本
# docker run -itd --name c4 --network bridge0 centos:latest
查看网段
# docker inspect 容器名 |grep IPAddress |tail -1
其实,真正需要添加的,也就只有bridge模式了。
13.跨docker的网络链接
以新机器为例,防火墙,网络,自行处理
模型以两台机器互联为例。
组件成员:
1.Docker:略
2.Flannel:为所有节点重新规划IP地址规则,从而重新获得"同属一个内网"且"不重复的"IP地址,让不同节点上的容器能通过内网IP通信。
3.Etcd:开源/分布式/键值对数据库,保存各个节点主机的子网网段信息。
先安装一台etcd机器
# yum install etcd
# vim /etc/etcd/etcd.conf
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" 0.0.0.0面向所有人开放
# systemctl start etcd
# systemctl enable etcd
每一台docker机上都要执行如下:
# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
# yum install flannel docker-ce -y
# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://etcd服务IP:2379" #注意:这里IP改为etcd服务IP
创建一个虚拟网络(我这里创建172.18.0.0/16)
# etcdctl mk //atomic.io/network/config '{"Network":"172.18.0.0/16"}'
{"Network":"172.18.0.0/16"}
# systemctl start flanneld
# systemctl enable flanneld
# cat /run/flannel/subnet.env
FLANNEL_NETWORK=172.18.0.0/16
FLANNEL_SUBNET=172.18.86.1/24 这是分配给你的IP端,各机器不同,容器内分配此网段IP
FLANNEL_MTU=1472
FLANNEL_IPMASQ=false
# systemctl start docker # 先启动docker才会产生/etc/docker/目录
# vim /etc/docker/daemon.json
# 内容如下:
{
"bip": "172.18.86.1/24",
"mtu": 1472
}
bip=FLANNEL_SUBNET 各机器不同。
mtu=FLANNEL_MTU
# systemctl restart docker
# ifconfig
docker0,flannel0应该都有IP了
验证:docker0,flannel0都有了之后基本成功,各自创建一个容器,ping另一个容器的IP地址即可。
ping不通要注意一下防火墙,selinux等等。
14.UI管理界面
# docker pull uifd/ui-for-docker
# docker run -d --name dockerui -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker
# docker pull portainer/portainer
# docker run -d -p 9001:9000 --name=portainer -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
直接访问即可