docker基础

云计算已经发展好些年了,作为运维,却接触不多。最近终于有时间可以研究一下docker了。

1、linux安装docker

2、镜像管理

3、容器管理

4、管理应用程序数据

5、网络管理

那docker究竟是什么呢?

  Docker是一个开源的应用容器引擎,使用Go语言开发,基于Linux内核的cgroup,namespace,Union FS等技术,对应用进程进行封装隔离,并且 独立于宿主机与其他进程,这种运行时封装的状态称为容器。 Docker早起版本实现是基于LXC,并进一步对其封装,包括文件系统、网络互联、镜像管理等方面,极大简化了容器管理。从0.7版本以后开始去 除LXC,转为自行研发的libcontainer,从1.11版本开始,进一步演进为使用runC和containerd。 Docker理念是将应用及依赖包打包到一个可移植的容器中,可发布到任意Linux发行版Docker引擎上。使用沙箱机制运行程序,程序之间相互隔离。

  

  Containerd:是一个简单的守护进程,使用runC管理容器。向Docker Engine提 供接口。 Shim:只负责管理一个容器。 runC:是一个轻量级的工具,只用来运行容器。 

 

docker内部组件

  • Namespaces

     命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。 

  • CGroups

    控制组,Linux内核提供的一种限制进程资源的机制;例如CPU、内存等资源。 

  • UnionFS

    联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层的模型。 

虚拟机与容器区别

   以KVM举例,与Docker对比

  1. 启动时间
    1. Docker秒级启动,KVM分钟级启动。
  2. 轻量级
    1. 容器镜像大小通常以M为单位,虚拟机以G为单位。
    2. 容器资源占用小,要比虚拟机部署更快速。
  3. 性能
    1. 容器共享宿主机内核,系统级虚拟化,占用资源少,没有Hypervisor层开销,容器性能基本接近物理机;
    2. 虚拟机需要Hypervisor层支持,虚拟化一些设备,具有完整的GuestOS,虚拟化开销大,因而降低性能,没有容器性能好。    
  4. 安全性
    1. 由于共享宿主机内核,只是进程级隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一定安全隐患。  
  5. 使用要求
    1. KVM基于硬件的完全虚拟化,需要硬件CPU虚拟化技术支持;
    2. 容器共享宿主机内核,可运行在主流的Linux发行版,不用考虑CPU是否支持虚拟化技术。

 

docker应用场景

  场景一:节省项目环境部署时间

      1. 单项目打包

      2. 整套项目打包

      3. 新开源技术试用

  场景二:环境一致性

  场景三:持续集成

  场景四:微服务

  场景五:弹性伸缩

 

一、linux安装docker。(本文仅提供centos7及ubuntu的安装方法,更多方式,请点击

CentOS7
# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker软件包源
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 更新yum包索引
yum makecache fast
# 安装Docker CE
yum install docker-ce
# 启动
systemctl start docker
# 卸载
yum remove docker-ce
rm -rf /var/lib/docker
Ubuntu14.06/16.04
# 安装证书
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
# 添加Docker源的KEY
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 添加Docker软件包源
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 更新apt包索引
sudo apt-get update
# 安装
sudo apt-get install docker-ce
# 卸载
sudo apt-get purge docker-ce
sudo rm -rf /var/lib/docker

 二、镜像管理

什么是镜像?

  简单说,Docker镜像是一个不包含Linux内核而又精简的Linux操作系统。

镜像从哪里来?

  Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。                         https://hub.docker.com/explore 默认是国外的源,下载会慢,建议配置国内镜像仓库:

  # vi /etc/docker/daemon.json

{
"registry-mirrors": [ "https://registry.docker-cn.com"] }

镜像和容器的关系

  

 

  镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history 查 看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在 /var/lib/docker/中。 容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写 到这个读写层。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。 Docker使用存储驱动管理镜像每层内容及可读写层的容器层。

存储驱动

  

镜像管理指令

  

指令 描述
ls 列出镜像
build 构建镜像来自Dockerfile
history 查看镜像历史
inspect 显示一个或多个镜像详细信息
pull 从镜像仓库拉取镜像
push 推送一个镜像到镜像仓库
rm 移除一个或多个镜像
prune 移除未使用的镜像。没有被标记或被任何容器引用的。
tag 创建一个引用源镜像标记目标镜像
export 导出容器文件系统到tar归档文件
import 导入容器文件系统tar归档文件创建镜像
save 保存一个或多个镜像到一个tar归档文件
load 加载镜像来自tar归档或标准输入

 

 三、容器管理

创建容器常用选项

管理容器常用命令

 

四、管理应用程序数据

Volume

管理卷:
# docker volume create nginx-vol
# docker volume ls
# docker volume inspect nginx-vol
用卷创建一个容器:
# docker run -d -it --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
# docker run -d -it --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
清理:
# docker container stop nginx-test
# docker container rm nginx-test
# docker volume rm nginx-vol
注意:
1. 如果没有指定卷,自动创建。
2. 建议使用—mount,更通用。
官方文档:https://docs.docker.com/engine/admin/volumes/volumes/#start-a-container-with-a-volume

Bind Mounts

 

用卷创建一个容器:
# docker run -d -it --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
# docker run -d -it --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
验证绑定:
# docker inspect nginx-test
清理:
# docker container stop nginx-test
# docker container rm nginx-test
注意:
1. 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。
2. 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。
官方文档:https://docs.docker.com/engine/admin/volumes/bind-mounts/#start-a-container-with-a-bind-mount

 

搭建LNMP网站平台

 

1、自定义网络
docker network create lnmp
2、创建Mysql数据库容器
docker run -itd \
--name lnmp_mysql \
--net lnmp \
-p 3306:3306 \
--mount src=mysql-vol,dst=/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456  \
mysql:5.7
--character-set-server=utf8
3、创建所需数据库
docker exec lnmp_mysql sh \
-c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"create database wp"'
4、创建PHP环境容器
docker run -itd \
--name lnmp_web \
--net lnmp \
-p 88:80 \
--mount type=bind,src=/app/wwwroot,dst=/var/www/html richarvey/nginx-php-fpm
5、以wordpress博客为例测试
wget https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz
tar zxf wordpress-4.7.4-zh_CN.tar.gz -C /app/wwwroot
# 浏览器测试访问
http://IP:88/wordpress

 

五、网络管理

网络模式

Docker支持5种网络模式 

bridge

  默认网络,Docker启动后默认创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。

host

  容器不会获得一个独立的network namespace,而是与宿主机共用一个。

none

  获取独立的network namespace,但不为容器进行任何网络配置。

container

  与指定的容器使用同一个network namespace,网卡配置也都是相同的。

自定义

  自定义网桥,默认与bridge网络一样。

Linux IP信息包过滤原理:

  Docker主要通过netfilter/iptables实现网络通信。 iptables由netfilter和iptables组成,netfilter组件是Linux内核集成的信息包过滤系统,它维护一个信息包过滤表,这个表用于控制信息包 过滤处理的规则集。而iptables只是一个在用户空间的工具,用于增删改查这个过滤表的规则。

容器访问外部
# iptables -t nat -nL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
外部访问容器
# iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:88 to:172.18.0.2:80

容器网络访问原理

 

 桥接宿主机网络与配置固定IP地址

临时生效:
# 网桥名称
br_name=br0
# 添加网桥
brctl addbr $br_name
# 给网桥设置IP
ip addr add 192.168.0.211/24 dev $br_name
# 删除已存在的eth0网卡配置
ip addr del 192.168.0.211/24 dev eth0
# 激活网桥
ip link set $br_name up
# 添加eth0到网桥
brctl addif $br_name eth0
# 添加路由
ip route add default via 192.168.0.1 dev br0
还需要在Docker启动时桥接这个网桥:
# vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -b=br0
# systemctl restart docker
永久生效:
# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BRIDGE=br0
# vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.211
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=114.114.114.114
配置固定IP
C_ID=$(docker run -itd --net=none ubuntu)
C_PID=$(docker inspect -f '{{.State.Pid}}' $C_ID)
# 创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取
mkdir -p /var/run/netns
ln -s /proc/$C_PID/ns/net /var/run/netns/$C_PID
# 添加虚拟网卡veth+容器PID,类型是veth pair,名称是vp+容器PID
ip link add veth$C_PID type veth peer name vp$C_PID
# 添加虚拟网卡到br0网桥
brctl addif br0 veth$C_PID
# 激活虚拟网卡
ip link set veth$C_PID up
# 设置容器网络信息
IP='192.168.0.123/24'
GW='192.168.0.1'
# 给进程配置一个network namespace
ip link set vp$C_PID netns $C_PID
# 在容器进程里面设置网卡信息
ip netns exec $C_PID ip link set dev vp$C_PID name eth0
ip netns exec $C_PID ip link set eth0 up
ip netns exec $C_PID ip addr add $IP dev eth0
ip netns exec $C_PID ip route add default via 192.168.1.1
pipework工具配置容器固定IP
git clone https://github.com/jpetazzo/pipework.git
cp pipework/pipework /usr/local/bin/
docker run -itd --net=none --name test01 ubuntu
pipework br0 test01 192.168.0.123/24@192.168.0.1

 

posted on 2018-05-29 11:46  法海降妖  阅读(180)  评论(0编辑  收藏  举报