docker安装/仓库/网络配置
- 1. docker 简介
- 2. 安装启用
- 3. 自建镜像
- 4. 优化自建镜像
- 5. 私有镜像仓库
- 6. 容器网络
1. docker 简介
Docker是管理容器的引擎。
Docker为应用打包、部署平台,而非单纯的虚拟化技术。
2. 安装启用
配置好yum源之后,安装启用。建议使用阿里云镜像。
https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/
yum install -y docker-ce
systemctl start docker
systemctl enable docker
下载好游戏镜像之后可以直接导入运行,访问宿主机IP
docker load -i game2048
docker run -d --name game1 -p 80:80 game2048
3. 自建镜像
查看容器镜像明细;
dockre inspect [images|containers]
-
commit
#运行容器docker run -it --name test busybox#修改容器/ # echo one > testfiledocker commit test test:v1 # 将test提交修改为:v1 #将容器保存为新的镜像docker images test:v1
查看镜像分层数据,无法审计新建层的内容:
-
Dockerfile
在dockerfile
中新建内容并进行镜像构建;每一条命令都会在镜像中新建一层,并且可以显示修改内容;构建镜像时会提交所有dockerfile
目录下的内容。
#创建Dockerfilecat Dockerfile FROM busyboxRUN echo one > testfile#构建镜像docker build -t test:v2 .
查看镜像分层数据,可以看到新建层的内容:
案例:封装nginx
镜像至rhel7 base
中
首先导入rhel7的base镜像
创建Dockerfile
,并且准备相应的yum
源与nginx
安装包;
vim Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb
ADD nginx-1.20.1.tar.gz /
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /nginx-1.20.1
RUN ./configure &> /dev/null
RUN make &> /dev/null
RUN make install &> /dev/null
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
构建镜像,并运行
查看运行容器id与ip,为挂载点添加网页内容,测试nginx
服务:
4. 优化自建镜像
在上节中nginx自建镜像完成的基础上,尽可能的使封装的镜像变小,对镜像进行优化。
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去用构建缓存
使用多阶段构建镜像
-
减少层数,多阶段构建以及清除缓存等
vim Dockerfile
FROM rhel7 as build
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/dvd.repo
WORKDIR /nginx-1.20.1
ADD nginx-1.20.1.tar.gz /
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure &> /dev/null && make &> /dev/null && make install &> /dev/null && rm -fr /nginx-1.20.1 /var/cache*FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
-
只使用nginx运行所需要的库文件构建
导入依赖库
vim Dockerfile
FROM nginx:latest as base
ARG TIME_ZONERUN 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/localtimeFROM gcr.io/distroless/base-debian10COPY --from=base /opt /EXPOSE 80 443ENTRYPOINT ["nginx", "-g", "daemon off;"]
构建镜像查看大小,此种方法可以减少绝大多部分内存
5. 私有镜像仓库
- 带证书的私有仓库
首先,生成证书认证文件,注意在生成证书时servername
或hostname
需要与仓库域名保持一致
mkdir -p certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -x509 -days 365 -out certs/westos.org.crt
下载官方registry镜像,并配置运行:
docker pull registry
docker run -d --name registry -v /opt/registry:/var/lib/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加载证书文件:
测试推送:
- 为仓库添加认证
首先,安装认证httpd-tools以生成认证文件,并添加用户。
yum install httpd-tools
mkdir auth
htpasswd -Bc auth/htpasswd admin
htpasswd -B auth/htpasswd user
设置镜像带认证文件运行
docker rm -f registry
docker run -d --name registry -v /opt/registry:/var/lib/registry -v "$(pwd)"/certs:/certs -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -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 login reg.westos.org
查看登陆信息,退出登陆:
cat /root/.docker/config.json
退出登陆,再查看登陆信息,授权已经消失:
docker logout reg.westos.org
6. 容器网络
原生网络
docker安装后会自动创建3种网络:host、none、bridge
- host 模式
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。容器与主机抢占网络资源。
host网络模式需要在容器创建时指定--network=host
- none 模式
none模式是指禁用网络功能,只有lo接口,在容器创建时使用--network=none
指定。 - bridge 模式
docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口。
容器如何访问外网是通过iptables
的SNAT
实现的。
而外网访问容器是通过DNAT
与docker-proxy
实现的。
宿主机访问本机容器使用的是iptables DNAT
,外部主机访问容器或容器之间的访问是docker-proxy
实现
自定义网络
使用自定义的网络可以让控制容器相互通信,自动DNS解析容器名称到IP地址。
docker network create -d bridge mynet #不指定网段建立
docker network create --subnet 172.25.0.0/24 --gateway 172.25.0.1 mynet #指定网段建立
使用--ip
参数可以指定容器ip地址,但必须是在自定义网桥上,默认的bridge
模式不支持,同一网桥上的容器是可以互通的。
# 指定网卡与 ip运行容器
docker run -d --name demo --network mynet --ip 172.25.0.2 rhel7:v88
# 不指定ip 指定网卡
docker run -d --name bb --network mynet busybox
在busybox
可以直接通过容器名访问demo
容器间相互通信
桥接到不同网桥上的容器,彼此相互无法通信。
- 添加网卡
可以向指定容器添加其他容器的网卡,实现相互通信
docker network connect NET Container
# 网卡设备 容器名
- Joined容器
在容器创建时使用--network=container:demo
指定 ,demo
为指定的容器名,此时两个容器功用网络栈,可以使用localhost
快速通信。
docker run -it demo2 --network=container:demo busybox
docker run -it demo2 --link demo:bb busybox
# bb为demo在demo2内的别名
跨主机通信
docker
原生的overlay
和macvlan
,第三方的flannel
、weave
、calico
,常用的为macvlan
。Container Network Model
对容器网络进行了抽象,从而集成在docker
内。
Sandbox
:容器网络栈,包含容器接口、dns、路由
Endpoint
:作用是将sandbox接入network (veth pair)
Network
:包含一组endpoint,同一network的endpoint可以通信。
- macvlan
这是Linux kernel
提供的一种网卡虚拟化技术,容器的接口直接与主机网卡连接,无需NAT
或端口映射。
macvlan
会独占主机网卡,但可以使用vlan
子接口实现多macvlan
网络,vlan
可以将物理二层网络划分为4094
个逻辑网络,彼此隔离,vlan id
取值为1~4094
打开网卡混杂模式:
ip link set eth0 promisc on
指定网卡创建macvlan
:
docker network create -d macvlan --subnet 172.66.0.0/24 --gateway 172.66.0.1 -o parent=eth0 macvlan1
在两台主机分别运行busybox
工作在同一macvlan
下测试相互通信。为容器指定macvlan运行时需要手动指定ip。
主机1:
ip link set eth0 promisc on
docker network create -d macvlan --subnet 172.66.0.0/24 --gateway 172.66.0.1 -o parent=eth0 macvlan1
docker run -it --name bb1 --network macvlan1 --ip 172.66.0.22 busybox
主机2:
ip link set eth0 promisc on
docker network create -d macvlan --subnet 172.66.0.0/24 --gateway 172.66.0.1 -o parent=eth0 macvlan1
docker run -it --name bb2 --network macvlan1 --ip 172.66.0.33 busybox
测试,busybox间可以相互通信:
- macvlan子接口
开启混杂口,创建macvlan指定网卡子接口,运行测试的busybox。
主机1:
ip link set eth0 promisc on
docker network create -d macvlan --subnet 172.88.0.0/24 --gateway 172.88.0.1 -o parent=eth0.1 macvlan1
docker run -it --name bb2 --network macvlan1 --ip 172.88.0.33 busybox
主机2:
ip link set eth0 promisc on
docker network create -d macvlan --subnet 172.88.0.0/24 --gateway 172.88.0.1 -o parent=eth0.1 macvlan1
docker run -it --name bb1 --network macvlan1 --ip 172.88.0.22 busybox
测试: