@zhangyy
2021-07-07T15:36:26.000000Z
字数 13947
阅读 195
docker的部分
- 一: docker 的介绍
- 二: 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:是一个轻量级的工具,只用来运行容器。
1. Namespaces
命名空间,Linux内核提供的一种对进程资源隔离的机制,例如进程、网络、挂载点等资源。
2. CGroups
控制组,Linux内核提供的一种限制进程资源的机制;例如CPU、内存等资源。
3. UnionFS
联合文件系统,支持将不同位置的目录挂载到同一虚拟文件系统,形成一种分层的模型。
以 KVM 举例,与 Docker 对比
启动时间
Docker秒级启动,KVM分钟级启动。
轻量级
容器镜像大小通常以M为单位,虚拟机以G为单位。
容器资源占用小,要比虚拟机部署更快速。
性能
容器共享宿主机内核,系统级虚拟化,占用资源少,没有Hypervisor层开销,容器性能基本接近物理机;
虚拟机需要Hypervisor层支持,虚拟化一些设备,具有完整的GuestOS,虚拟化开销大,因而降低性能,没有容器性能好。
安全性
由于共享宿主机内核,只是进程级隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主机内核,存在一定安全隐患。
使用 要求
KVM基于硬件的完全虚拟化,需要硬件CPU虚拟化技术支持;
容器共享宿主机内核,可运行在主流的Linux发行版,不用考虑CPU是否支持虚拟化技术。
场景一:节省项目环境部署时间
1. 单项目打包
2. 整套项目打包
3. 新开源技术试用
场景二:环境一致性
场景三:持续集成
场景四:微服务
场景五:弹性伸缩
参看: http://blog.51cto.com/lizhenliang/1978081
CentOS7
# 安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加Docker软件包源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 更新yum包索引
yum makecache fast
# 安装Docker CE
yum install docker-ce -y
# 启动
systemctl start docker
# 卸载
yum remove docker-ce
rm -rf /var/lib/docker
官方安装文档:
https://docs.docker.com/engine/installation/linux/docker-
ce/centos/#docker-ee-customers
linux 修改时区的方法
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
date -s "2018-01-27 14:17:00"
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操作系统。
---
镜像是什么?
• 一个分层存储的文件
• 一个软件的环境
• 一个镜像可以创建N个容器
• 一种标准化的交付
• 一个不包含Linux内核而又精简的Linux操作系统
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME> 查看镜像中各层内容及大小,每层
对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/\<storage-driver\>中。
镜像从哪里来?
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。
地址:https://hub.docker.com/explore
配置镜像加速器:https://www.daocloud.io/mirror
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
---
镜像从哪里来?
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。
https://hub.docker.com/explore
默认是国外的源,下载会慢,建议配置国内镜像仓库:
# vi /etc/docker/daemon.json
{
"registry-mirrors": [ "https://registry.docker-cn.com"]
}
----
重启一下:
systemctl restart docker
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME> 查
看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在
/var/lib/docker/<storage-driver>中。
容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写
到这个读写层。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。
Docker使用存储驱动管理镜像每层内容及可读写层的容器层。
如图,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,
会先从镜像里要写的文件复制到容器自己的文件系统中(读写层)。
如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多
少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作
的,并不会修改镜像的源文件,这种方式提高磁盘利用率。
若想持久化这些改动,可以通过docker commit 将容器保存成一个新镜像。
docker image pull httpd ## 拉取一个镜像
去这里 下载:
https://download.openvz.org/template/precreated/
cat centos-6-x86_64-minimal.tar.gz |docker import - centos:6.0 ## 创建镜像
cat centos-7-x86_64-minimal.tar.gz |docker import - centos:7.0
cat ubuntu-16.04-x86_64.tar.gz |docker import - ubuntu:16.04
docker image ls ## 列出所有镜像
docker image history httpd 查看镜像的分层历史
docker image inspect nginx 查看 一个镜像的具体信息
docker image pull nginx:1.11 # 下载一个镜像
保存一个镜像:
docker image save nginx:1.11 > nginx1.11.tar.gz
删除一个一个镜像
docker image rm nginx:1.11
导入一个镜像
docker image load < nginx1.11.tar.gz
导出正在容器 的文件系统
docker export f376547bcb01 > http.tar.gz
导入容器
docker import http.tar.gz http:v2
创建一个容器
docker container run -ti http:v2 /bin/bash ## 创建一个容器,退出就关闭了
docker container start 9bfd4
进入一个容器
docker container exec -ti 9bfd4 /bin/bash
容器与外面端口的映射
docker container run -tid -p 8080:80 nginx:1.11 /bin/bash
docker container exec -ti c4a659 /bin/bash
service nginx start
创建一个一直在运行的服务
docker container run -tid --name nginx01 --restart=always nginx:1.11
创建容器,限制容器的cpu
docker container run --help |grep cpu
docker container run -tid --memory 512M --cpus 1 --name nginx02 nginx:1.11
查看使用的量
docker container stats
查看有哪些容器
docker container ls
查看容器的详细信息
docker container inspect c44023d07aab
附加到容器
docker container attach c44 ### 如果 容器正在运行程序则进不了容器
docker container exec c44 /bin/bash ### 进入的容器必须是已经启动的容器
提交一个容器到镜像 仓库
docker container commit c44023d07aab nginx:test1
向容器中复制东西
docker container cp anaconda-ks.cfg nginx02:/root
docker container exec nginx02 ls /root
docker container logs nginx02 ### 查看容器的日志
docker container port c4a6593972f6 ## 查看容器的映射端口
Docker提供三种不同的方式将数据从宿主机挂载到容器中:volumes,bind mounts和tmpfs。
volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。
bind mounts:可以存储在宿主机系统的任意位置。
tmpfs:挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统。
cd /var/lib/docker/volumes
docker volume create nginx-vol
docker volume ls
docker run -d -it --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx ### 创建容器并使用建好的volume 卷处理
docker volume create nginxz-vol
docker volume ls
docker run -tid --name=nginxz --mount src=nginxz-vol,dst=/usr/local nginxz:1.11
docker volume create httpd-vol
docker volume ls
docker run -tid --name=httpd-test --mount src=httpd-vol,dst=/usr/local httpd
如果一个数据卷可以挂载在不同的容器当中,就可以实现端口的负载了
进入这个容器
docker container exec -ti nginx-test bash
cd /usr/share/nginx/html/
touch 1.txt
退出容器
cd /var/lib/docker/volume/nginx-vol/_data/
ls -ld *
删除所有容器
docker rm -f $(docker ps -q -a)
用卷创建 一个容器:
# mkdir -p /app/www/html
# docker run -d -it --name=nginx-test --mount type=bind,src=/app/www/html,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. 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏
Docker报错 WARNING: IPv4 forwarding is disabled. Networking will not work.
# vim /usr/lib/sysctl.d/00-system.conf
加上:
net.ipv4.ip_forward=1
重启网卡:
service network restart
0 、 宿主机安装mysql8.0
rpm -e mariadb-devel mariadb-libs mariadb --nodeps
yum install -y perl-JSON
rm -rf mysql-community-server-minimal-8.0.11-1.el7.x86_64.rpm
rpm -ivh mysql-community-*
1 、自定义网络
docker network create lnmp
2 、创建 Mysql 数据库容器
docker run -itd \
--name lnmp_mysql \
--net lnmp \
-p 3306:3306 \
--mount src=mysql-vol,dst=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql --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
容器的访问:
iptables -I INPUT -s 0.0.0.0 -j ACCEPT
iptables -I INPUT -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
# 浏览器测试访问
http://IP:88/wordpress/
数据的主机填写lnmp_mysql是docker的构建的mysql的名字
Docker 支持 5 种 网络模式
1. bridge
默认网络,Docker启动后默认创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
2. host
容器不会获得一个独立的network namespace,而是与宿主机共用一个。
3. none
获取独立的network namespace,但不为容器进行任何网络配置。
4. container
与指定的容器使用同一个network namespace,网卡配置也都是相同的。
5. 自定义
自定义网桥,默认与bridge网络一样。
docker 的 bridge 网络
Docker 容器默认使用 bridge 模式的网络。其特点如下:
使用一个 linux bridge,默认为 docker0
使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上
该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与veth pair的 IP地址不在同一个网段内
Docker采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口port 进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部
外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port
NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过NAT建立通信
host 模式
docker run -tid --name centos_host1_test --net host centos_test
会与宿主机公用一个网络
none 模式
docker run -tid --name centos1_none --net none centos_test
这个模式下面是单独的网络,没有IP 地址
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
创建一个容器:
docker run -ti --name centos_test /bin/bash
临时网络
# 网桥名称
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 -tid --name centos1_none --net none centos_test
pipework br0 centos1_none 172.17.100.11/24@172.17.100.2
进入这个容器
docker exec -ti e95dff5 bash
这个只是临时配置的,重启容器就丢了,docker 不建议这样做。
Usage: docker image build [OPTIONS] PATH | URL | -
Options:
-t, --tag list # 镜像名称
-f, --file string # 指定Dockerfile文件位置
示例:
docker build .
docker build -t shykes/myapp .
docker build -t shykes/myapp -f /path/Dockerfile /path
FROM centos:7
MAINTAINER www.aliangedu.com
RUN yum install -y gcc gcc-c++ make openssl-devel pcre-devel
ADD nginx-1.12.1.tar.gz /tmp
RUN cd /tmp/nginx-1.12.1 && \
./configure --prefix=/usr/local/nginx && \
make -j 2 && \
make install
RUN rm -rf /tmp/nginx-1.12.1* && yum clean all
COPY nginx.conf /usr/local/nginx/conf
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["./sbin/nginx", "-g", "daemon off;"]
----
执行构建
cd nginx/
docker build -t nginx:v1 -f Dockerfile .
FROM centos:7
MAINTAINER www.aliangedu.com
RUN yum install -y gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-
devel libpng-devel openssl-devel
ADD php-5.6.31.tar.gz /tmp/
RUN cd /tmp/php-5.6.31 && \
./configure --prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-mysql --with-mysqli \
--with-openssl --with-zlib --with-curl --with-gd \
--with-jpeg-dir --with-png-dir --with-iconv \
--enable-fpm --enable-zip --enable-mbstring && \
make -j 4 && \
make install && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
sed -i "s/127.0.0.1/0.0.0.0/" /usr/local/php/etc/php-fpm.conf && \
sed -i "21a \daemonize = no" /usr/local/php/etc/php-fpm.conf
COPY php.ini /usr/local/php/etc
RUN rm -rf /tmp/php-5.6.31* && yum clean all
WORKDIR /usr/local/php
EXPOSE 9000
CMD ["./sbin/php-fpm", "-c", "/usr/local/php/etc/php-fpm.conf"]
-----
执行构建命令
cd /root/php/
docker build -t php:v1 -f Dockerfile .
1 、自定义网络
docker network create lnmp
2 2 、创建 PHP 容器
docker run -itd \
--name lnmp_php \
--net lnmp \
--mount type=bind,src=/app/wwwroot/,dst=/usr/local/nginx/html \
php:v1
3 3 、创建 Nginx 容器
mkdir -p /app/wwwroot/
docker run -itd \
--name lnmp_nginx \
-p 888:80 \
--net lnmp \
--mount type=bind,src=/app/wwwroot/,dst=/usr/local/nginx/html \
nginx:v1
4 4 、创建 MySQL 容器
docker run -itd \
--name lnmp_mysql \
--net lnmp \
-p 3306:3306 \
--mount src=mysql-vol,dst=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql --character-set-server=utf8
FROM centos:7
MAINTAINER www.aliangedu.com
ADD jdk-8u45-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_45
ADD apache-tomcat-8.0.46.tar.gz /usr/local
COPY server.xml /usr/local/apache-tomcat-8.0.46/conf
RUN rm -f /usr/local/*.tar.gz
WORKDIR /usr/local/apache-tomcat-8.0.46
EXPOSE 8080
ENTRYPOINT ["./bin/catalina.sh", "run"]
-------------
cd /root/tomcat/
docker build -t tomcat:v1 -f Dockerfile .
------------
开启容器:
mkdir -p /app/webapps/
docker run -itd \
--name=tomcat \
-p 8080:8080 \
--mount type=bind,src=/app/webapps/,dst=/usr/local/apache-tomcat-8.0.46/webapps \
tomcat:v1
cd /app/webapps/
mkdir ROOT
cd ROOT
echo "hello world" >> index.html
Docker Hub作为Docker默认官方公共镜像;如果想自己搭建私有镜像仓库,官方也提供registry镜像,使得搭建私有仓库非常简单。
下载 registry 镜像并启动
# docker pull registry
# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry
测试 ,查看镜像仓库中所有镜像
# curl http://172.17.100.11:5000/v2/_catalog
{"repositories":[]}
搭建私有镜像仓库
1 1 、配置 私有仓库可信任
# vi /etc/docker/daemon.json
{"insecure-registries":["172.17.100.11:5000"]}
# systemctl restart docker
2 、打标签
# docker tag centos7.0:v1 172.17.100.11:5000/centos7.0:v1
3 、上 传
# docker push 172.17.100.11:5000/centos7.0
4 、下载
# docker pull 172.17.100.11:5000/centos7.0
5 、列出 镜像标签
# curl http://172.17.100.11:5000/v2/centos7.0/tags/list
私有镜像仓库管
1 、注册账号
https://hub.docker.com
2 、登录 Docker Hub
# docker login
或
# docker login --username=zhangyy --password=123456
3 、镜像打标签
# docker tag wordpress:v1 zhangyy/wordpress:v1
4 、上传
# docker push zhangyy/wordpress:v1
搜索测试:
# docker search zhangyy
5 、下载
# docker pull zhangyy/wordpress:v1
Portainer是一个开源、轻量级Docker管理用户界面,基于Docker API,可管理Docker主机或Swarm集群,支持最新版Docker和Swarm模式。
1 1 、创建卷
# docker volume create portainer_data
2 2 、创建P P ortainer 容器
# docker run -d \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer
创建一个网络
docker create network monitor
Influxdb
docker run -d \
--name influxdb \
--net monitor \
-p 8083:8083 \
-p 8086:8086 \
tutum/influxdb
cAdvisor
docker run -d \
--name=cadvisor \
--net monitor \
-p 8081:8080 \
--mount type=bind,src=/,dst=/rootfs,ro \
--mount type=bind,src=/var/run,dst=/var/run \
--mount type=bind,src=/sys,dst=/sys,ro \
--mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker,ro \
google/cadvisor \
-storage_driver=influxdb \
-storage_driver_db=cadvisor \
-storage_driver_host=influxdb:8086
Grafana
docker run -d \
--name grafana \
--net monitor \
-p 3000:3000 \
grafana/grafana