Docker介绍
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker的应用场景
Web 应用的自动化打包和发布。
自动化测试和持续集成、发布。
在服务型环境中部署和调整数据库或其他的后台应用。
从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
Docker 的优点
Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker能够将应用程序与基础架构分开,从而可以快速交付软件。借助 Docker,可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker的方法来快速交付,测试和部署代码,可以大大减少编写代码和在生产环境中运行代码之间的延迟。
1、快速,一致地交付您的应用程序
Docker 允许开发人员使用自己提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。
2、响应式部署和扩展
Docker 是基于容器的平台,允许高度可移植的工作负载。Docker容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。
Docker 的可移植性和轻量级的特性,可以轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。
3、在同一硬件上运行更多工作负载
Docker轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此可以利用更多的计算能力来实现业务目标。Docker非常适合于高密度环境以及中小型部署,可以用更少的资源做更多的事情。
Docker 架构
Docker 包括三个基本概念:
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。Docker 使用客户端-服务器 (C/S)
架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
容器与镜像的关系类似于面向对象编程中的对象与类。
Docker的安装部署
yum install docker-ce -y ##有依赖性,需要配置相关仓库
systemctl enable --now docker
docker info ##查看信息,但会有两个警告
sysctl -a | grep bridge-nf-call-iptables
vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
sysctl --system ##刷新
docker search yakexi007
docker pull yakexi007/game2048
docker run -d --name demo -p 80:80 yakexi007/game2048
docker rm -f demo
一、Docker镜像
镜像的构建
docker commit 构建新镜像三部曲
运行容器
修改容器
将容器保存为新的镜像
缺点:
效率低、可重复性弱、容易出错
使用者无法对镜像进行审计,存在安全隐患
docker pull busybox ##拉取镜像
docker images ##查看当前所有下载镜像
docker run -it --name demo1 busybox ##运行容器,-i表示交互式,-t表示打开伪终端,demo1不能重复
docker ps -a
docker rm demo1 ##删除容器
当在demo1中进行操作后删除demo1,镜像中操作的内容不会保存
docker run -it --name demo1 busybox
docker commit demo1 demo1:v1 ##将容器保存为新的镜像
当在v1中进行操作后删除demo1,v1镜像中操作的内容不受影响
docker images demo1:v1 ##查看镜像
docker history demo1:v1
docker history busybox:latest
对比查看两者层级结构
demo:v1是在busybox的基础上又添加了一层但并没有显示具体操作
docker rm demo1
docker run -it --name demo1 demo1 busybox
文件导入镜像
docker rm demo1 ##删除demo1镜像
docker rmi demo1:v1 ##删除v1镜像
mkdir docker
cd docker/
docker search nginx
vim Dockerfile
FROM busybox
RUN echo "hello word"
RUN touch file1
docker build -t demo2:v1 . ##构建镜像 -t表示tag镜像名字及tag
docker history demo2:v1 ##查看镜像的分层结构,会显示具体操作
docker run -it --rm demo2:v1 ##打开镜像发现已经创建指定文件
Dockerfile详解
docker rmi `docker images |grep webserver | awk '{print $1":"$2}'` ##删除webserver的镜像
当需要给镜像容器内放入文件,在默认目录下必须存在该文件
docker load -i rhel7.tar
vim Dockerfile
FROM rhel7
RUN touch file1
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.21.1.tar.gz /mnt
WORKDIR "/mnt/nginx-1.21.1"
RUN rpmdb --rebuilddb ##用于初始化和重建rpm数据库
RUN yum install -y gcc pcre-devel zlib-devel make
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
FROM busybox #镜像来源
RUN echo westos > testfile # RUN后跟shell运行语句
RUN echo hello > testfile1
COPY index.html / #COPY拷贝当前目录的index.html到容器的根目录下
ADD nginx-1.20.1.tar.gz / #ADD 解压tar包到根目录下
ENV HOSTNAME server1 #ENV 定义变量HOSTNAME为server1
EXPOSE 80 #设定端口为80
VOLUME {"/data"} #挂载目录为/data
WORKDIR /data #工作空间为 /data
ENTRYPOINT ["/bin/echo", "hello"] #强制输出不被覆盖
CMD ["world"] #输出会覆盖
docker build -t webserver:v1
docker build -t webserver:v1 .
docker run -d --name nginx webserver:v1
docker ps -a
docker inspect 2d74f4ea8d4e
curl 172.17.0.3
镜像的优化
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去用构建缓存
使用多阶段构建镜像
mkdir optimize
docker load -i base-debian10.tar
vim Dockerfile
vim /new/Dockerfile
FROM nginx:latest as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian10
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
docker build -t webserver:v2 .
docker run -d --name demo webserver:v2
docker inspect demo
curl 172.17.0.2
二、Docker仓库
配置镜像加速器
vim /etc/docker/daemon.json
{
“registry-mirrors”: [“https://wtqu29tl.mirror.aliyuncs.com”]
}
systemctl daemon-reload
systemctl restart docker
本地仓库的搭建
删除废弃镜像
docker pull registry
docker run -d --name registry -p 5000:5000 registry ##运行registry容器
docker tag webserver:v2 localhost:5000/webserver:latest ##本地镜像在命名时需要加上仓库的ip和端口
docker push localhost:5000/webserver ##上传镜像到本地仓库
docker rmi localhost:5000/webserver:latest
docker rmi webserver:v2
docker pull localhost:5000/webserver
cd openssl11/
加密
yum install -y *
docker rm -f registry
mkdir ~/certs
openssl11 req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -addext “subjectAltName = DNS:reg.westos.org” -x509 -days 365 -out certs/westos.org.crt
vim /etc/hosts
172.25.22.1 reg.westos.org
docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key -p 443:443 registry
docker ps
cd /etc/docker/
mkdir certs.d
cd certs.d/
mkdir reg.westos.org
cd reg.westos.org/
cp ~/certs/westos.org.crt ca.crt
ping reg.westos.org
docker tag nginx:latest reg.westos.org/nginx:latesteeeee
docker push reg.westos.org/nginx:latest
认证
docker rm -f registry
docker run -d -p 443:443 --restart=always --name registry -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key registry
docker login reg.westos.org
cat /root/.docker/config.json
docker push reg.westos.org/nginx:latest
网页登陆
tar zxf harbor-offline-installer-v1.10.1.tgz
mv docker-compose-Linux-x86_64-1.27.0 /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
cd harbor/
vim harbor.yml
mkdir /data
./install.sh
docker-compose ps
docker info ##添加默认仓库位置
vim /etc/docker/daemon.json
systemctl reload docker.service
docker info
docker login reg.westos.org
访问172.25.22.1
上传镜像
docker tag nginx:latest reg.westos.org/library/nginx:latest
docker push reg.westos.org/library/nginx:latest
docker-compose down
cd /var/lib/docker/volumes/
docker volume prune
cd /data/
rm -rf *
cp ~/certs/ /data/ -r
cd harbor/
./prepare
./install.sh --with-notary --with-clair --with-chartmuseum
docker tag nginx:latest reg.westos.org/library/nginx:latest
docker push reg.westos.org/library/nginx:latest
优化容器
cd /usr/local/bin/
rm -rf *
mv docker-compose-linux-x86_64-v2.0.1 docker-compose
chmod +x docker-compose
systemctl reload docker.service
cd harbor/
docker-compose ps
docker tag yakexi007/game2048:latest reg.westos.org/library/game2048:latest ##可上网
cd ~/.docker/
mkdir tls
cd tls
mkdir reg.westos.org\:4443
cd reg.westos.org\:4443/
cp /etc/docker/certs.d/reg.westos.org/ca.crt .
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://reg.westos.org:4443
docker push reg.westos.org/library/nginx:latest
docker push reg.westos.org/library/game2048:latest
三、网络
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分。docker安装后会自动创建3种网络:bridge、host、none;
首先将前面的harbor仓库停掉
cd ~/harbor/
docker-compose down
vim /etc/docker/daemon.json
https://wtqu29tl.mirror.aliyuncs.com/ systemctl reload docker.service
unset DOCKER_CONTENT_TRUST
env
macvlan主机网卡实现
跨主机容器网络
在两台docker主机上各添加一块网卡,打开网卡混杂模式:
server1
vim /etc/sysconfig/network-scripts/ifcfg-eth1
BOOTPROTO=none
DEVICE=eth1
ONBOOT=yesserver2
vim /etc/sysconfig/network-scripts/ifcfg-eth1
BOOTPROTO=none
DEVICE=eth1
ONBOOT=yesserver1
ip addr show eth1
ifup eth1
ip link set eth1 promisc on
ip addr show eth1
docker network prune ##删除之前的网络配置
docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parent=eth1 macvlan1
docker network inspect macvlan1
docker run -it --rm --network macvlan1 --ip 10.0.0.10 busyboxplus
docker run -d --name web1 --network macvlan1 --ip 10.0.0.10 nginx
server2
yum install -y docker-ce
systemctl enable --now docker
ip addr show eth1
docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parent=eth1 macvlan1
docker search busyboxplus
docker pull redial/busyboxplus
docker tag radial/busyboxplus:latest busyboxplus:latest
docker rmi radial/busyboxplus:latest
docker run -it --rm --network macvlan1 --ip 10.0.0.11 busyboxplus
macvlan子接口实现
server1
docker network create -d macvlan --subnet 20.0.0.0/24 --gateway 20.0.0.1 -o parent=eth1.1 macvlan2
docker run -it --rm --network macvlan2 --ip 20.0.0.10 busyboxplus
s
erver2
docker network create -d macvlan --subnet 20.0.0.0/24 --gateway 20.0.0.1 -o parent=eth1.1 lan2
docker run -it --rm --network macvlan2 --ip 20.0.0.11 busyboxplus
Docker数据卷管理
docker提供了两种卷:
bind mount
docker managed volume
bind mount
是将主机上的目录或文件mount到容器里。
使用直观高效,易于理解。
使用 -v 选项指定路径,格式 :
默认权限是读写rw,可以在挂载时指定只读ro。
-v选项指定的路径,如果不存在,挂载时会自动创建。
server1
docker run -it --rm -v /opt/data:/data busyboxplus
docker run -it --rm -v /opt/data:/data:ro busyboxplus
docker run -it --rm -v /opt/data:/data:ro -v /opt/data1:/data1 busyboxplus
docker managed volume
bind mount必须指定host文件系统路径,限制了移植性。
docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录。
默认创建的数据卷目录都在 /var/lib/docker/volumes 中。
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。
server1
docker volume ls ##默认数据卷存放位置
docker volume prune ##清除数据卷
docker volume create webdata1
docker volume inspect webdata1
docker run -d --name demo -v webdata1:/usr/share/nginx/html nginx
curl 172.17.0.2
cd /var/lib/docker/volumes/webdata1/_data/
docker run -d --name demo1 -v /opt/data3:/usr/share/nginx/html nginx
cd /opt/data3
echo web1 > index.html
curl 172.17.0.3
bind mount与docker managed volume对比
相同点:两者都是 host 文件系统中的某个路径。
不同点:
卷插件简介
server1
convoy卷插件
yum install nfs-utils -y
vim /etc/exports
/mnt/nfs *(rw,no_root_squash)
showmount -e
mkdir /mnt/nfssystemctl start nfs
tar zxf convoy-v0.5.2.tar.gz
cd convoy/
mv convoy* /usr/local/bin/
mkdir -p /etc/docker/plugins
echo “unix:///var/run/convoy/convoy.sock” > /etc/docker/plugins/convoy.spec
convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
ps ax
docker volume ls
convoy create vol1
convoy list
docker volume ls
docker run -d --name vole1 -v vol1:/usr/share/nginx/html:ro nginx
curl 172.17.0.2
cd /mnt/nfs/vol1/
echo web1 > index.html
docker save -o nginx.tar nginx:latest
scp nginx.tar server2:
server2
yum install -y nfs-utils
showmount -e 172.25.22.1
mkdir /mnt/nfs
mount 172.25.22.1:/mnt/nfs/ /mnt/nfs/
tar zxf convoy-v0.5.2.tar.gz
cd convoy/
mv convoy* /usr/local/bin/
mkdir -p /etc/docker/plugins
echo “unix:///var/run/convoy/convoy.sock” > /etc/docker/plugins/convoy.spec
convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
docker volume ls
docker load -i nginx.tar
docker run -d --name vole1 -v vol1:/usr/share/nginx/html:ro nginx
curl 172.17.0.2
Docker Machine