目录
Docker 是一个开源的应用容器引擎,主要利用 linux 内核 namespace 实现沙盒隔离,用
cgroup 实现资源限制
一、Docker镜像下载与安装
下载地址:docker-ce镜像-docker-ce下载地址-docker-ce安装教程-阿里巴巴开源镜像站
配置源
[root@server1 ~]# cd /etc/yum.repos.d/
[root@server1 yum.repos.d]# curl https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o docker-ce.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2081 100 2081 0 0 6282 0 --:--:-- --:--:-- --:--:-- 6287
[root@server1 yum.repos.d]# vim docker-ce.repo

安装centOS源
centos镜像-centos下载地址-centos安装教程-阿里巴巴开源镜像站
[root@server1 yum.repos.d]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2523 100 2523 0 0 8976 0 --:--:-- --:--:-- --:--:-- 8978
[root@server1 yum.repos.d]# vim CentOS-Base.repo
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/extras/$basearch/
gpgcheck=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
只激活[extras]
其他都enabled=0
安装docker-ce
[root@server1 yum.repos.d]# yum install -y docker-ce
[root@server1 yum.repos.d]# systemctl enable --now docker
[root@server1 yum.repos.d]# docker info
查看有警告

是网桥有问题,配置网桥
[root@server1 yum.repos.d]# cd /etc/docker/
[root@server1 docker]# sysctl -a |grep bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 0
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.docker0.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.eth1.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
[root@server1 docker]# vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
[root@server1 docker]# sysctl --system

测试:下载容器库中的数据
[root@server1 ~]# docker pull yakexi007/game2048
Using default tag: latest
latest: Pulling from yakexi007/game2048
534e72e7cedc: Pull complete
f62e2f6dfeef: Pull complete
fe7db6293242: Pull complete
3f120f6a2bf8: Pull complete
4ba4e6930ea5: Pull complete
Digest: sha256:8a34fb9cb168c420604b6e5d32ca6d412cb0d533a826b313b190535c03fe9390
Status: Downloaded newer image for yakexi007/game2048:latest
docker.io/yakexi007/game2048:latest
[root@server1 ~]# docker run -d --name demo -p 80:80 yakexi007/game2048
dcda3e27fc9e553043aeee96971547d1a2ac92ef897a1871a4e1bd435a8a78cf
访问172.25.6.1

删除
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcda3e27fc9e yakexi007/game2048 "/bin/sh -c 'sed -i …" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp demo
[root@server1 ~]# docker rm -f demo
demo
安装 busybox
[root@server1 ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
5cc84ad355aa: Pull complete
Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest beae173ccac6 4 days ago 1.24MB
yakexi007/game2048 latest 19299002fdbe 5 years ago 55.5MB
[root@server1 ~]# docker run -it --name demo busybox 这里输入命令,ctrl d退出
/ # ls
bin dev etc home proc root sys tmp usr var
/ # touch file
/ # ls
bin dev etc file home proc root sys tmp usr var
/ # rm -f file
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 ~]# docker ps -a 查看进程
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad118e314332 busybox "sh" 54 seconds ago Exited (0) 29 seconds ago demo
[root@server1 ~]# docker rm demo 删除进程
demo
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

二、 镜像的分层结构
- 共享宿主机的kernel
- base镜像提供的是最小的Linux发行版
- 同一docker主机支持运行多种Linux发行版
- 采用分层结构的最大好处是:共享资源


- Copy-on-Write 可写容器层
- 容器层以下所有镜像层都是只读的
- docker从上往下依次查找文件
- 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
- 一个镜像最多127层

[root@server1 ~]# docker start demo
demo
[root@server1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bbb644964514 busybox "sh" 4 minutes ago Up 6 seconds demo
[root@server1 ~]# docker attach demo
/ # ls
bin dev etc home proc root sys tmp usr var
/ # touch file1
/ # touch file2
/ # touch file3
/ # ls
bin etc file2 home root tmp var
dev file1 file3 proc sys usr
/ # read escape sequence ##ctrl q p后台运行
三、 镜像的构建
docker commit
docker commit 构建新镜像三部曲
- 运行容器
- 修改容器
- 将容器保存为新的镜像
缺点:
效率低、可重复性弱、容易出错
使用者无法对镜像进行审计,存在安全隐患
[root@server1 ~]# docker commit demo demo:v1 提交镜像
sha256:c7eba38f8d62ca0b8c5968d0676fbe96eafe33fd4b87700b08c531e164290835
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
demo v1 c7eba38f8d62 25 seconds ago 1.24MB
busybox latest beae173ccac6 4 days ago 1.24MB
yakexi007/game2048 latest 19299002fdbe 5 years ago 55.5MB
[root@server1 ~]# docker history demo:v1
IMAGE CREATED CREATED BY SIZE COMMENT
c7eba38f8d62 44 seconds ago sh 51B
beae173ccac6 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:6db446a57cbd2b7f4… 1.24MB
[root@server1 ~]# docker history busybox:latest
IMAGE CREATED CREATED BY SIZE COMMENT
beae173ccac6 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 4 days ago /bin/sh -c #(nop) ADD file:6db446a57cbd2b7f4… 1.24MB
[root@server1 ~]# docker rm demo
demo
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server1 ~]# docker run -it --rm demo:v1
/ # ls
bin etc file2 home root tmp var
dev file1 file3 proc sys usr
/ #
[root@server1 ~]# docker run -it --rm busybox
/ # ls
bin dev etc home proc root sys tmp usr var
但这样提交看不到操作记录

创建Dockerfile
我们可以用创建Dockerfile的方法构建镜像
[root@server1 ~]# mkdir docker
[root@server1 ~]# cd docker/
[root@server1 docker]# vim Dockerfile
FROM busybox
RUN touch file1 file2 file3
~
[root@server1 docker]# docker build -t demo:v2 .
[root@server1 docker]# docker images
[root@server1 docker]# docker history demo:v2

Dockerfile常用命令
FROM
指定base镜像,如果本地不存在会从远程仓库下载
RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包
[root@server1 docker]# vim Dockerfile
FROM busybox
RUN touch file1 file2 file3
CMD echo "hello world"
[root@server1 docker]# docker build -t demo:v3 .
[root@server1 docker]# docker run --rm demo:v3
hello world

COPY
把文件从build context复制到镜像
支持两种形式:COPY src dest 和 COPY ["src", "dest"]
src必须指定build context中的文件或目录
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# echo www.westos.org > index.html
[root@server1 docker]# ls
Dockerfile index.html
[root@server1 docker]# docker build -t demo:v4 .
[root@server1 docker]# docker history demo:v4
[root@server1 docker]# docker run --rm demo:v4 cat /index.html

ADD
用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像
[root@server1 docker]# vim Dockerfile
ADD nginx-1.20.2.tar.gz /
[root@server1 docker]# docker build -t demo:v5 .
[root@server1 docker]# docker run --rm demo:v5 ls /

ENV
设置环境变量,变量可以被后续的指令使用
[root@server1 docker]# vim Dockerfile
ENV hostname server1
CMD echo $hostname
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# docker build -t demo:v6 .
[root@server1 docker]# docker run --rm demo:v6

EXPOSE
如果容器中运行应用服务,可以把服务端口暴露出去
EXPOSE 80
[root@server1 docker]# docker run -d --name demo -p 80:8080 yakexi007/mario
[root@server1 docker]# docker ps
[root@server1 docker]# docker port demo



网桥会自动分配一个ip


VOLUME
申明数据卷,通常指定的是应用的数据挂在点
VOLUME ["/data"]
[root@server1 docker]# docker build -t demo:v7 .
[root@server1 docker]# docker history demo:v7
[root@server1 docker]# docker run -it --rm demo:v7 sh
/ # ls
bin etc file3 nginx-1.20.2 sys var
data file1 home proc tmp
dev file2 index.html root usr
/ # cd data
/data # touch file
/data # ls
file
/data # rm -f file
/data # cp /index.html .
/data # ls
index.html
/data #
[root@server1 docker]# docker inspect 07167cc0ecac
[root@server1 docker]# cd /var/lib/docker/volumes/96113ea9cc0f4343d0491ea6cf4e338d8a913a37550e6205d85696cc3fddf139/_data ##容器和此目录是互通的
[root@server1 _data]# ls
index.html
[root@server1 _data]# rm -f index.html
[root@server1 _data]# cp /etc/passwd .
[root@server1 _data]# ls
passwd
[root@server1 _data]# docker attach 07167cc0ecac
/data # ls
passwd


查看信息可以查看到所关联目录


CMD 与 ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
CMD ["/bin/echo", "$hostname"]
[root@server1 docker]# docker build -t demo:v8 .
[root@server1 docker]# docker run --rm demo:v8
$hostname
[root@server1 docker]# docker rmi demo:v8
CMD无法识别echo
![]()
修改一下
CMD ["/bin/sh","-c","echo $hostname"]
[root@server1 docker]# docker run --rm demo:v8
server1
![]()
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
~
[root@server1 docker]# docker build -t demo:v9 .
[root@server1 docker]# docker run --rm demo:v9
hello world
[root@server1 docker]# docker run --rm demo:v9 linux
hello linux
[root@server1 docker]# docker run --rm demo:v9 linux redhat
hello linux redhat

四、创建nginx镜像及优化
[root@server1 ~]# docker images | grep demo | awk '{system("docker rmi "$1":"$2"")}'
删除之前创建的
[root@server1 ~]# docker pull centos
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest beae173ccac6 4 days ago 1.24MB
centos latest 5d0da3dc9764 3 months ago 231MB
yakexi007/game2048 latest 19299002fdbe 5 years ago 55.5MB
yakexi007/mario latest 9a35a9e43e8c 6 years ago 198MB
[root@server1 ~]# docker history centos:latest
IMAGE CREATED CREATED BY SIZE COMMENT
5d0da3dc9764 3 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] ##如果有cmd运行时后面可以不加sh,否则要加sh 0B
<missing> 3 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 3 months ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0… 231MB
配置yum源
[root@server1 docker]# docker run -it --name demo centos
[root@ea60710ad825 /]# cd /etc/yum.repos.d
[root@ea60710ad825 yum.repos.d]# rm -fr *
[root@ea60710ad825 yum.repos.d]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
[root@ea60710ad825 yum.repos.d]# ls
CentOS-Base.repo
[root@ea60710ad825 yum.repos.d]# vi CentOS-Base.repo
需要[AppStream]和[base]
安装nginx
docker cp nginx-1.20.2.tar.gz demo:/ ##复制压缩包到容器
[root@server1 docker]# docker run -it --name demo centos
[root@ea60710ad825 /]# tar zxf nginx-1.20.2.tar.gz
[root@ea60710ad825 /]# cd /etc/yum.repos.d
[root@ea60710ad825 yum.repos.d]# rm -fr *
[root@ea60710ad825 yum.repos.d]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo
[root@ea60710ad825 yum.repos.d]# ls
CentOS-Base.repo
[root@ea60710ad825 yum.repos.d]# vi CentOS-Base.repo
需要[AppStream]和[base]
[root@ea60710ad825 yum.repos.d]# yum repolist
Failed to set locale, defaulting to C.UTF-8
repo id repo name
AppStream CentOS-8 - AppStream - mirrors.aliyun.com
base CentOS-8 - Base - mirrors.aliyun.com
[root@ea60710ad825 yum.repos.d]# yum install -y gcc pcre-devel openssl-devel make
[root@ea60710ad825 nginx-1.20.2]# vi auto/cc/gcc
# debug
#CFLAGS="$CFLAGS -g"
[root@ea60710ad825 nginx-1.20.2]# ./configure --with-http_ssl_module
[root@ea60710ad825 nginx-1.20.2]# make
[root@ea60710ad825 nginx-1.20.2]# make install
[root@ea60710ad825 sbin]# ./nginx
[root@ea60710ad825 sbin]# ps ax
PID TTY STAT TIME COMMAND
1 pts/0 Ss 0:00 /bin/bash
4926 ? Ss 0:00 nginx: master process ./nginx
4927 ? S 0:00 nginx: worker process
4928 pts/0 R+ 0:00 ps ax
封装镜像
[root@server1 docker]# vim Dockerfile
FROM centos
RUN rm -f /etc/yum.repos.d/*.repo
COPY CentOS-Base.repo /etc/yum.repos.d/
RUN yum install -y gcc pcre-devel openssl-devel make
ADD nginx-1.20.2.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.2
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --with-http_ssl_module
RUN make
RUN make install
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
[root@server1 docker]# docker build -t webserver:v1 .
[root@server1 docker]# docker run -d --name demo webserver:v1
415d680eeb95953c79d959f14fb1ecd68b90e8d6bf8efd0e0e57ca552013b706

测试

镜像的优化
- 选择最精简的基础镜像
- 减少镜像的层数
- 清理镜像构建的中间产物
- 注意优化网络请求
- 尽量去用构建缓存
- 使用多阶段构建镜像
减少镜像的层数
FROM centos
RUN rm -f /etc/yum.repos.d/*.repo
COPY CentOS-Base.repo /etc/yum.repos.d/
RUN yum install -y gcc pcre-devel openssl-devel make
ADD nginx-1.20.2.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.2
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module && make && make install && rm -fr /mnt/nginx-1.20.2 && yum clean
all
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
~
[root@server1 docker]# docker build -t webserver:v2 .
变化不是很大

使用多阶段构建镜像
FROM centos as build
RUN rm -f /etc/yum.repos.d/*.repo
COPY CentOS-Base.repo /etc/yum.repos.d/
RUN yum install -y gcc pcre-devel openssl-devel make
ADD nginx-1.20.2.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.2
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module && make && make install && rm -fr /mnt/nginx-1.20.2 && yum clean all
FROM centos
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t webserver:v3 .
[root@server1 docker]# docker run -it --rm webserver:v3 bash
[root@de006fcab9e1 /]# ldd /usr/local/nginx/sbin/nginx
linux-vdso.so.1 (0x00007ffff2dc2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f3786c42000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3786a22000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f37867f2000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f378657a000)
libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007f37862e2000)
libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007f3785dfa000)
libz.so.1 => /lib64/libz.so.1 (0x00007f3785be2000)
libc.so.6 => /lib64/libc.so.6 (0x00007f378581a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3786e4a000)
缩减很多

选择最精简的基础镜像
可以在官网中寻找
GitHub: Where the world builds software · GitHub
[root@server1 docker]# vim Dockerfile
FROM nginx:1.18.0 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;"]
需要拉取nginx和依赖
[root@server1 ~]# docker load -i base-debian10.tar
[root@server1 docker]# docker pull nginx:1.18
[root@server1 docker]# docker build -t webserver:v4 .
可以看到缩减很多, 所以在实际构建中尽量选择最精简的base镜像

测试
[root@server1 docker]# docker inspect demo1
[root@server1 docker]# curl 172.17.0.3

五、建立私有仓库
删除不用的容器 docker images | grep webserver | awk '{system("docker rmi "$1":"$2"")}'
我们先下载registry镜像
[root@server1 ~]# docker pull registry
[root@server1 ~]# docker history registry:latest 查看到5000端口
[root@server1 ~]# docker run -d --name registry -p 5000:5000 registry 运行容器
[root@server1 ~]# docker ps
[root@server1 ~]# docker tag busybox:latest localhost:5000/busybox:latest 设置标签
[root@server1 ~]# docker images


上传至仓库
[root@server1 ~]# docker push localhost:5000/busybox:latest
删除之前拉取的,重新从私有仓库拉取
[root@server1 ~]# docker rmi busybox:latest
[root@server1 ~]# docker rmi localhost:5000/busybox
[root@server1 ~]# docker pull localhost:5000/busybox:latest

搭建仓库帮助文档
Deploy a registry server | Docker Documentation
证书认证
Test an insecure registry | Docker Documentation
需要安装openssl11
[root@server1 ~]# mkdir certs
[root@server1 ~]# 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 填写证书内容
Country Name (2 letter code) [XX]:cn
State or Province Name (full name) []:shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:westos
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:reg.westos.org
Email Address []:root@westos.org


运行
Deploy a registry server | Docker Documentation
[root@server1 ~]# docker run -d --restart=always --name registry -v /root/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
[root@server1 ~]# vim /etc/hosts/ ##添加地址解析
172.25.6.1 server1 reg.westos.org
[root@server1 ~]# docker tag localhost:5000/busybox:latest reg.westos.org/busybox:latest
[root@server1 ~]# docker push reg.westos.org/busybox:latest
此时会出现错误

证书有问题,我们需要将证书放在指定目录下
[root@server1 ~]# cd /etc/docker
[root@server1 docker]# ls
daemon.json key.json
[root@server1 docker]# mkdir certs.d
[root@server1 docker]# cd certs.d/
[root@server1 certs.d]# mkdir reg.westos.org
[root@server1 certs.d]# cd reg.westos.org/
[root@server1 reg.westos.org]# cp /root/certs/westos.org.crt ca.crt
[root@server1 reg.westos.org]# ls
ca.crt
[root@server1 reg.westos.org]# pwd
/etc/docker/certs.d/reg.westos.org
[root@server1 ~]# docker push reg.westos.org/busybox:latest
重新上传成功

[root@server1 ~]# yum install -y httpd-tools
添加用户和密码
[root@server1 ~]# htpasswd -cB auth/htpasswd admin
New password:
Re-type new password:
Adding password for user admin
[root@server1 ~]# htpasswd -B auth/htpasswd xmm
New password:
Re-type new password:
Adding password for user xmm
[root@server1 ~]# cat auth/htpasswd

再次运行

清理不需要的倦
[root@server1 ~]# docker volume ls
DRIVER VOLUME NAME
local 1bbb07cd9402d2a3fd791018a36d5c0ee61abb20243e883f07e7638792712e81
local 25a81c8b9a4def461375201a7717551246f07a6c9d10fc22e209d62aa96cce6c
local 003545d2afc68f345bbe013328fd098463f0ada38522e770afd42e47a4b60fe6
[root@server1 ~]# docker volume prune
再次push会出现错误

需要登陆用户
[root@server1 ~]# docker login reg.westos.org
Username: admin
Password:

再次push成功

测试
[root@server1 ~]# curl -u admin:westos -k https://reg.westos.org/v2/_catalog
{"repositories":["busybox"]}
registry工作原理

index服务主要提供镜像索引以及用户认证的功能。当下载一个镜像的时候,首先会去index服务上做认证,然后查找镜像所在的registry的地址并放回给docker客户端,docker客户 端再从registry下载镜像,在下载过程中registry会去index校验客户端token的合法性,不同镜像可以保存在不同的registry服务上,其索引信息都放在index服务上。
六、配置镜像加速器
阿里云加速器
每个账户加速器地址不同
用户中心——工作台——镜像工具——镜像加速器

[root@server1 ~]# cd /etc/docker/
[root@server1 docker]# vim daemon.json
[root@server1 docker]# systemctl daemon-reload
[root@server1 docker]# systemctl restart docker
[root@server1 docker]# docker info

官方加速器
同理,只是地址不同
[root@server1 docker]# vim daemon.json

七、构建企业级仓库harbor
[root@server1 ~]# docker rm -f registry
[root@server1 ~]# mv docker-compose-linux-x86_64-v2.0.1 /usr/local/bin/docker-compose
[root@server1 ~]# chmod +x /usr/local/bin/docker-compose
[root@server1 ~]# tar zxf harbor-offline-installer-v2.3.4.tgz
[root@server1 ~]# cd harbor/
[root@server1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@server1 harbor]# vim harbor.yml ##更改配置文件
hostname: reg.westos.org
certificate: /data/certs/westos.org.crt
private_key: /data/certs/westos.org.key
harbor_admin_password: westos

建立证书目录
[root@server1 harbor]# mkdir /data
[root@server1 harbor]# cd
[root@server1 ~]# mv certs/ /data/
[root@server1 ~]# cd /data
[root@server1 data]# ls
certs
[root@server1 data]# cd certs/
[root@server1 certs]# ls
westos.org.crt westos.org.key
安装
[root@server1 harbor]# mkdir /var/log/harbor/
[root@server1 harbor]# ./install.sh

访问172.25.6.1登陆harbor

docker-compose ps只能在 docker-compos.yml所在目录中使用

重新登陆一下

重新上传
[root@server1 ~]# docker tag reg.westos.org/busybox:latest reg.westos.org/library/busybox:latest
[root@server1 ~]# docker push reg.westos.org/library/busybox:latest
[root@server1 ~]# docker tag nginx:latest reg.westos.org/library/nginx:latest
[root@server1 ~]# docker push reg.westos.org/library/nginx
可以在前端看到上传的镜像

新开一台主机
[root@server1 docker]# scp -r certs.d/ server2:/etc/docker/
[root@server1 docker]# scp daemon.json server2:/etc/docker/
[root@server2 ~]# vim /etc/hosts
172.25.6.1 server1 reg.westos.org
[root@server2 docker]# vim daemon.json
[root@server2 docker]# systemctl daemon-reload
[root@server2 docker]# systemctl reload docker

拉取镜像,可以发现是从仓库中拉取的
[root@server2 docker]# docker pull nginx

安装harbor一些插件
[root@server1 harbor]# docker-compose stop
[root@server1 harbor]# docker-compose down
[root@server1 harbor]# ./install.sh --with-notary --with-trivy --with-chartmuseum
之后我们可以进行扫描,扫描的网速如果太慢,可以直接将离线库解压到/data/trivy-adapter/trivy/db 注意权限
[root@server1 db]# chown 10000.10000 metadata.json
[root@server1 db]# chown 10000.10000 trivy.db
[root@server1 trivy]# chown 10000.10000 db

扫描完成

内容信任开启后,其他主机没有签名无法从仓库下载 

我们需要加入认证
[root@server1 ~]# cd .docker/
[root@server1 .docker]# ls
config.json
[root@server1 .docker]# mkdir tls/reg.westos.org:4443 -p
[root@server1 .docker]# cd tls/
[root@server1 tls]# ls
reg.westos.org:4443
[root@server1 tls]# cd reg.westos.org\:4443/
[root@server1 reg.westos.org:4443]# cp /etc/docker/certs.d/reg.westos.org/ca.crt .
[root@server1 reg.westos.org:4443]# ls
ca.crt
[root@server1 reg.westos.org:4443]# export DOCKER_CONTENT_TRUST=1
[root@server1 reg.westos.org:4443]# export DOCKER_CONTENT_TRUST_SERVER=https://reg.westos.org:4443
[root@server1 ~]# docker push reg.westos.org/library/nginx:latest
[root@server1 ~]# docker tag nginx:1.18 reg.westos.org/library/nginx:1.18
[root@server1 ~]# docker push reg.westos.org/library/nginx:1.18
看签名为绿色,此主机2可以拉取

[root@server2 docker]# docker pull nginx拉取之后可以在日志看到记录

八、Docker 原生网络
bridge
docker安装时会创建一个名为docker0的linux bridge,新建的容器会自动桥接到这个接口
[root@server2 docker]# yum install -y bridge-utils.x86_64
[root@server2 docker]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.02426c2351ec no
[root@server2 docker]# docker run -d --name demo nginx
[root@server2 docker]# docker inspect demo
运行nginx会自动分配一个docker网段的ip地址
ip分配递增


- bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。
- 容器通过宿主机的NAT规则后可以访问外网。

容器通过桥接到达宿主机,宿主机通过linux路由到达eth0,做伪装之后出去,所以此时容器可以访问外网

host
host网络模式需要在容器创建时指定 --network=host
host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但容器的网络缺少隔离性。
宿主机如果占用端口,容器不可以再用
举例:开两个nginx,只能开启一个容器

查看日志会发现提示端口被占用

none
none模式是值禁用网络功能,只有lo接口,在容器创建时使用 --network=none指定

九、Docker 自定义网络
自定义网络模式,docker提供了三种自定义网络驱动:
- bridge
- overlay
- macvlan
bridge驱动类似默认的bridge网络模式, 但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络。
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。
docker1.10开始,内嵌了一个DNS server
ip是动态的,一旦重现开启容器,ip很可能会变
没用解析无法ping容器

创建一个自定义网络

默认是172.18

比docker0递增

自己指定一个网段


默认不可以指定ip,创建时定义了子网的可以

运行指定mynet1此时可以ping域名到demo2

运行指定mynet2此时也可以ping域名到demo1

但它们之间是隔离的,彼此是不通信的
通过使用docker network connect命令给server1添加一块网卡来使不同网桥的容器通信

ctrl+p+q后台运行
默认接入mynet1,加网卡接入mynet2

此时就可以ping通了

十、Docker容器通信
容器之间除了使用ip通信外,还可以使用容器名称通信。
- docker 1.10开始,内嵌了一个DNS server。
- dns解析功能必须在自定义网络中使用。
- 启动容器时使用--name参数指定容器名称。
Joined容器一种较为特别的网络模式。
--network
在容器创建时使用--network=container:vm1指定(vm 1指定的是运行的容器名)
[root@server2 docker]# docker container prune 删除所有未运行的容器

[root@server2 ~]# docker pull radial/busyboxplus
[root@server2 ~]# docker tag radial/busyboxplus:latest busyboxplus:latest
[root@server2 ~]# docker rmi radial/busyboxplus:latest

处于这个模式下Docker容器会共享同一网络栈,这样两个容器之间可以使用localhost高效快速通信
--link
--link 可以用来链接2个容器。
--link的格式:
- --Jink <name or id>:alias
- name和id是源容器的name和id, alias是源容器在link下的别名。

会自动解析


容器访问外网

外网访问容器
- 端口映射
- -p选项指定映射端口
[root@server2 ~]# docker run -d --name demo -p 80:80 nginx
2119701a38d73b4fc9e6285e6db74679bd956450f08372627e37a99c6bb6581d
[root@server2 ~]# docker port demo
80/tcp -> 0.0.0.0:80
80/tcp -> :::80

双冗余机制,proxy和iptable只要有一个在就可以进行通信

十一、跨主机容器网络
跨主机网络解决方案
- docker原生的overlay和macvlan
- 第三方的flannel. weave. calico
众多网络方案是如何与docker集成在一-起的
- libnetwork docker容器网络库
- CNM (Container Network Model) 这个模型对容器网络进行了抽象
macvlan网络方案实现
- Linux kernel提供的一种网卡虚拟化技术。
- 无需Linux bridge,直接使用物理接口,性能极好。
在两台docker主机上各添加一块网卡,打开网卡混杂模式:
[root@server1 harbor]# cd /etc/sysconfig/network-scripts/
[root@server1 network-scripts]# cp ifcfg-eth0 ifcfg-eth1
[root@server1 network-scripts]# vim ifcfg-eth1
[root@server1 network-scripts]# ifup eth1
[root@server1 network-scripts]# ip link set eth1 promisc on

2中同理
[root@server1 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parent=eth1 macvlan1
[root@server2 ~]# docker network create -d macvlan --subnet 10.0.0.0/24 --gateway 10.0.0.1 -o parent=eth1 macvlan1
[root@server2 ~]# docker network create -d macvlan --subnet 192.168.0.0/24 --gateway 192.168.0.1 -o parent=eth1.1 macvlan2
[root@server1 ~]# docker network create -d macvlan --subnet 192.168.0.0/24 --gateway 192.168.0.1 -o parent=eth1.1 macvlan2



设置server2都为192.168网段,此时互通

macvlan网络间的隔离和连通
- macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。.
- 可以在三层上通过网关将macvlan网络连通起来。
- docker本身不做任何限制,像传统vlan网络那样管理即可。

[root@server2 ~]# docker network connect macvlan1 demo3

十二、Docker数据卷
docker分层文件系统
- 性能差
- 生命周期容器相同
docker数据卷
- mount到主机中,绕开分层文件系统
- 和主机磁盘性能相同,容器删除后依然保留
- 仅限本地磁盘,不能随容器迁移
docker提供了两种卷:
- bind mount
- docker managed volume
bind mount
[root@server2 ~]# mkdir website
[root@server2 ~]# cd website/
[root@server2 website]# echo www.westos.org > index.html
[root@server2 website]# cd
[root@server2 ~]# docker run -d --name demo -v /root/website/:/usr/share/nginx/html nginx
此时访问一下,容器目录和本地目录同步

bind mount默认权限是读写rw,可以在挂载时指定只读ro。
-v选项指定的路径,如果不存在,挂载时会自动创建。


docker managed volume
docker managed volume
- bind mount必须指定host文件系统路径,限制了移植性。
- docker managed volume不需要指定mount源,docker 自动为容器创建数据卷目录。
- 默认创建的数据卷目录都在/var/lib/docker/volumes中。
- 如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。
[root@server1 ~]# docker run -d --name demo registry
[root@server1 ~]# docker inspect demo
可以看到路径

创建


bind mount与docker managed volume对比
相同点:两者都是host文件系统中的某个路径。
不同点:

卷插件
docker卷默认使用的是local类型的驱动,只能存在宿主机,跨主机的volume就需要使用第三方的驱动。
docker官方只提供了卷插件的api,开发者可以根据实际需求定制卷插件驱动。
- Docker Plugin是以Web Service的服务运行在每一台Docker Host上的,通过HTTP协议传输RPC风格的JSON数据完成通信。
- Plugin的启动和停止,并不归Docker管理,Docker Daemon依靠在缺省路径下查找Unix Socket文件,自动发现可用的插件。
- 当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的socket 文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。
convoy
convoy卷插件实现
- 支持三种运行方式: devicemapper. NFS. EBS.
- 在所有节点提前挂载NFS存储
[root@server1 ~]# tar zxf convoy-v0.5.2.tar.gz
[root@server1 convoy]# cp convoy convoy-pdata_tools /usr/local/bin
[root@server1 convoy]# cd /usr/local/bin
[root@server1 bin]# ll
total 65024
-rwxr-xr-x 1 root root 17607008 Jan 7 15:29 convoy
-rwxr-xr-x 1 root root 23068627 Jan 7 15:29 convoy-pdata_tools
-rwx--x--x 1 root root 25907200 Jan 5 11:48 docker-compose
[root@server1 bin]# mkdir -p /etc/docker/plugins
[root@server1 bin]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
[root@server1 bin]# cat etc/docker/plugins/convoy.spec
cat: etc/docker/plugins/convoy.spec: No such file or directory
[root@server1 bin]# cat /etc/docker/plugins/convoy.spec
unix:///var/run/convoy/convoy.sock
所有节点都安装nfs-utils
[root@server1 ~]# vim /etc/exports
/mnt/nfs *(rw,no_root_squash)
[root@server1 ~]# mkdir /mnt/nfs
[root@server1 ~]# systemctl start nfs
[root@server2 ~]# mkdir /mnt/nfs
[root@server2 ~]# mount 172.25.6.1:/mnt/nfs /mnt/nfs
[root@server1 ~]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[1] 6067
[root@server1 ~]# cd /etc/docker/plugins/
[root@server1 plugins]# convoy create vol1
[root@server1 ~]# docker volume create -d convoy vol2


server2中同理
[root@server2 plugins]# docker run -it --rm -v vol1:/data2 busybox

如果删除plugins,重启会非常慢,此时可以删除var/lib/docker/volumes/metadata.db
十三、Docker安全
Docker安全简介
Docker容器的安全性,很大程度上依赖于Linux系统自身,评估Docker的安全性时,主要考虑以下几个方面:
- Linux内核的命名空间机制提供的容器隔离安全。
- Linux控制组机制对容器资源的控制能力安全。
- Linux内核的能力机制所带来的操作权限安全。
- Docker程序 (特别是服务端)本身的抗攻击性。
- 其他安全增强机制对容器安全性的影响。
控制组资源控制的安全
- 当docker run启动一个容器时Docker将在后台为容器创建一个独立的控制组策略集合。
- Linux Cgroups提供了很多有用的特性,确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。
- 确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务攻击(DDoS)方面必不可少。
Docker服务端防护
- 使用Docker容器的核心是Docker服务端, 确保只有可信的用户才能访问到Docker服务。
- 将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题。
- 允许Docker服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。
其他安全特性
- 在内核中启用GRSEC和PAX,这将增加更多的编译和运行时的安全检查;并且通过地址随机化机制来避免恶意探测等。启用该特性不需要Docker进行任何配置。
- 使用一些有增强安全特性的容器模板。
- 用户可以自定义更加严格的访问控制机制来定制安全策略。
- 在文件系统挂载到容器内部时,可以通过配置只读模式来避免容器内的应用通过文件系统破坏外部环境,特别是一些系统运行状态相关的目录。
容器资源控制
在/sys/fs/cgroup 下面有很多诸如cpuset、cpu、 memory这样的子目录,也叫子系统。
在每个子系统下面,为每个容器创建一个控制组(即创建一个新目录),
控制组下面的资源文件里填上什么值,就靠用户执行docker run时的参数指定。
CPU限额
- docker run -it --cpu-period= 100000 --cpu-quota=20000 ubuntu
- cpu_ period和cpu_ quota这两个参效需要组合使用,用来限制进程在长度为cpu_ period 的一段时间内,只能被分配到总量为cpu_ quota 的CPU时间,以上设置表示20%的cpu时间。
Block IO限制
docker run -it --device-write-bps /dev/sda :30MB ubuntu
--device-write- bps限制写设备的bps
目前的block IO限制只对direct IO有效。(不使用文件缓存)
十四、Docker安全加固
LXCFS
利用LXCFS增强docker容器隔离性和资源可见性
我们直接限制内存时,查看是直接查看到宿主机的内存,看不到限制结果,所以需要增强容器隔离性,然后挂载到容器内查看。
[root@server1 ~]# yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm -y
[root@server1 ~]# lxcfs /var/lib/lxcfs &
[root@server1 proc]# pwd
/var/lib/lxcfs/proc
[root@server1 proc]# ls
cpuinfo diskstats meminfo stat swaps uptime

[root@server1 proc]# docker run -it --rm -m 200M -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw -v /var/lib/lxcfs/proc/stat:/proc/stat:rw -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw ubuntu
root@5dc1c39f5135:/# free -m

设置特权级运行的容器: --privileged=true
有的时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载USB磁盘,修改MAC地址等,相当于给了root权限
默认是普通用户权限,没有权限管理网络、磁盘等

我们开启权限
[root@server1 proc]# docker run -it --rm --privileged=true busybox

设置容器白名单: --cap-add
--privileged=true的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时Docker 提供了权限白名单的机制,使用--cap-add添加必要的权限。
例:只添加网络管理的权限
[root@server1 proc]# docker run -it --rm --cap-add=NET_ADMIN busybox

安全加固的思路
保证镜像的安全
- 使用安全的基础镜像
- 删除镜像中的setuid和setgid权限
- 启用Docker的内容信任
- 最小安装原则
- 对镜像进行安全漏洞扫描,镜像安全扫描器: Clair
- 容器使用非root用户运行
保证容器的安全
- 对docker宿主机进行安全加固
- 限制容器之间的网络流量
- 配置Docker守护程序的TLS身份验证
- 启用用户命名空间支持(userns-remap)
- 限制容器的内存使用量
- 适当设置容器CPU优先级
Docker安全的顶尖开源工具
- Docker Bench for Security 对照安全基准审计Docker容器的脚本
- Clair API驱动的静态容器安全分析工具,拥有庞大的CVE数据库
- Cilium 内核层可感知API的网络和安全工具
- Anchore 使用CVE数据和用户定义的策略检查容器安全的工具
- OpenSCAP Workbench 用于为各种平台创建和维护安全策略的环境
- Dagda 用于在Docker容器中扫描漏洞、特洛伊木马、病毒和恶意软件的工具
- Notary 使用服务器加强容器安全的框架,用于以加密方式委派责任
- Sysdig Falco 提供了行为活动监控,可深入了解容器
十五、Docker Machine
- Docker Machine是Docker官方编排项目之一,负责在多种平台上快速安装Docker 环境。
- Docker Machine支持在常規Linux操作系统、虚拟化平台、openstack、公有云等不同环境下安装配置docker host。
- Docker Machine项目基于Go语言实现
安装
[root@server1 ~]# mv docker-machine-Linux-x86_64-0.16.2 /usr/local/bin/docker-machine
[root@server1 ~]# chmod +x /usr/local/bin/docker-machine
创建machine:
创建machine要求免密登陆远程主机:
[root@server1 ~]# ssh-keygen
[root@server1 ~]# ssh-copy-id server2
[root@server1 ~]# ssh-copy-id server3
创建主机:
[root@server1 ~]# docker-machine create --driver generic --generic-ip-address=172.25.6.2 server2

server2开启2376端口

登陆到server2
[root@server1 ~]# docker-machine env server2
[root@server1 ~]# eval $(docker-machine env server2)
登陆之后没有符号显示,安装bash脚本
[root@server1 ~]# mv *.bash /etc/bash_completion.d/
docker-machine.bash docker-machine-prompt.bash docker-machine-wrapper.bash
[root@server1 ~]# vim .bashrc
PS1='[\u@\h \W$(__docker_machine_ps1)]\$ '
[root@server1 ~]# logout
Connection to 172.25.6.1 closed.
[westos@foundation37 Desktop]$ ssh -l root 172.25.6.1
root@172.25.6.1's password:
Last login: Mon Jan 10 09:43:39 2022 from foundation37.ilt.example.com
[root@server1 ~]# eval $(docker-machine env server2)

此时重新登陆有提示符了

给没有安装docker的主机server3中创建
[root@foundation37 html]# curl https://get.docker.com/ -o get-docker.sh
[root@foundation37 html]# vim get-docker.sh
[root@foundation37 html]# vim docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/$releasever/$basearch/stable
enabled=1
gpgcheck=0
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
baseurl=http://mirrors.aliyun.com/centos/7/extras/$basearch/
gpgcheck=0
[root@server1 ~]# docker-machine create --driver generic --generic-ip-address=172.25.6.3 --engine-install-url "http://172.25.6.250/get-docker.sh" server3


十六、Docker Compose
Docker Compose简介
- 微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低,维护量之大可想而知。
- Docker Compose是一种编排服务,基于pyhton语言实现,是一个用于在Docker上定义并运行复杂应用的工具,可以让用户在集群中部署分布式应用。
- 用户可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。
- 解决了容器与容器之间如何管理编排的问题。
Docker Compose中两个重要概念:
- 服务(service) :一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
- 项目(project):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。
Docker Compose实践
Compose file version 3 reference | Docker Documentation
docker-compose.yml属性
- Image: 指定为镜像名称或镜像ID,如果镜像在本地不存在,Compose将会尝试拉取这个镜像。
- Build:指定Dockerfile所在文件夹的路径。Compose将会利用它自动构建这个镜像,然后使用这个镜像。
- Command:覆盖容器启动后默认执行的命令。
- Links:链接到其它服务中的容器。
- Ports: 端口映射。
- Expose:暴露端口信息
- Volumes:卷挂载路径设置
[root@server1 ~]# docker pull haproxy
[root@server1 ~]# mkdir compose
[root@server1 ~]# cd compose/
[root@server1 compose]# vim docker-compose.yml
version: "3.9"
services:
web1:
image: nginx
networks:
- mynet
volumes:
- ./web1:/usr/share/nginx/html
web2:
image: nginx
networks:
- mynet
volumes:
- ./web2:/usr/share/nginx/html
haproxy:
image: haproxy
networks:
- mynet
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
ports:
- "80:5000"
networks:
mynet:
[root@server1 compose]# docker network prune
[root@server1 compose]# mkdir web1
[root@server1 compose]# echo web1 > web1/index.html
[root@server1 compose]# mkdir web2
[root@server1 compose]# echo web2 > web2/index.html
[root@server1 compose]# mkdir haproxy
[root@server1 compose]# cd haproxy/
[root@server1 haproxy]# vim haproxy.cfg
#
# This is a sample configuration. It illustrates how to separate static objects
# traffic from dynamic traffic, and how to dynamically regulate the server load.
#
# It listens on 192.168.1.10:80, and directs all requests for Host 'img' or
# URIs starting with /img or /css to a dedicated group of servers. URIs
# starting with /admin/stats deliver the stats page.
#
global
maxconn 65535
#stats socket /var/run/haproxy.stat mode 600 level admin
log 127.0.0.1 local0
#uid 200
#gid 200
#chroot /var/empty
daemon
defaults
mode http
log global
option httplog
option dontlognull
monitor-uri /monitoruri
maxconn 8000
timeout client 30s
retries 2
option redispatch
timeout connect 5s
timeout server 5s
stats uri /admin/stats
# The public 'www' address in the DMZ
frontend public
bind *:5000 name clear
#bind 192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem
#use_backend static if { hdr_beg(host) -i img }
#use_backend static if { path_beg /img /css }
default_backend dynamic
# The static backend backend for 'Host: img', /img and /css.
backend dynamic
balance roundrobin
server a web1:80 check inter 1000
server b web2:80 check inter 1000
[root@server1 compose]# docker-compose start
[root@server1 compose]# docker-compose ps
[root@foundation37 html]# curl 172.25.6.1
web2
[root@foundation37 html]# curl 172.25.6.1
web1

使用curl命令可以看出负载均衡

十七、Docker Swarm
- Swarm在Docker 1.12 版本之前属于一个独立的项目,在Docker1.12版本发布之后,该项目合并到了Docker中,成为Docker的一个子命令。
- Swarm是Docker社区提供的唯一一个原生支持Docker集群管理的工具。
- Swarm可以把多个Docker主机组成的系统转换为单一的虚拟Docker主机,使得容器可以组成跨主机的子网网络。
- Docker Swarm是一个为IT运维团队提供集群和调度能力的编排工具。
docker swarm相关概念
- 节点分为管理(manager)节点和工作(worker)节点
- 任务(Task) 是Swarm中的最小的调度单位,目前来说就是一个单一的容器。
- 服务(Services) 是指一组任务的集合,服务定义了任务的属性。
[root@server1 ~]# docker swarm init
[root@server2 sysctl.d]# scp docker.conf server3:/etc/sysctl.d
[root@server3 yum.repos.d]# sysctl --system
[root@server2 ~]# docker swarm join --token SWMTKN-1-265u9jlnmt808kyx1oorl96r552faf79ypeswmgwzfc3kacqrb-8ykijt2t5tvzci7pl4vniguor 172.25.6.1:2377
This node joined a swarm as a worker.
[root@server3 ~]# docker swarm join --token SWMTKN-1-265u9jlnmt808kyx1oorl96r552faf79ypeswmgwzfc3kacqrb-8ykijt2t5tvzci7pl4vniguor 172.25.6.1:2377
This node joined a swarm as a worker.
将server1设置为私有仓库
[root@server1 ~]# docker node promote server2
Node server2 promoted to a manager in the swarm.
[root@server1 ~]# docker node demote server1
[root@server1 ~]# docker swarm leave
[root@server2 ~]# docker node rm server1
[root@server1 harbor]# docker-compose up -d
[root@server2 docker]# scp -r certs.d/ server3:/etc/docker/
[root@server2 docker]# scp daemon.json server3:/etc/docker/
[root@server3 docker]# systemctl daemon-reload
[root@server3 docker]# systemctl reload docker
[root@server3 docker]# docker pull nginx
增加新节点
[root@server4 ~]# yum install -y docker-ce
[root@server4 ~]# systemctl start docker
[root@server4 ~]# vim /etc/hosts
172.25.6.1 server1 reg.westos.org
[root@server3 yum.repos.d]# scp docker-ce.repo server4:/etc/yum.repos.d/
[root@server3 yum.repos.d]# cd /etc/sysctl.d/
[root@server3 sysctl.d]# scp docker.conf server4:/etc/sysctl.d/
[root@server3 docker]# scp -r certs.d/ daemon.json server4:/etc/docker/
[root@server2 ~]# docker service create --name webcluster -p 80:80 --replicas 3 nginx
[root@server4 ~]# docker swarm join --token SWMTKN-1-265u9jlnmt808kyx1oorl96r552faf79ypeswmgwzfc3kacqrb-8ykijt2t5tvzci7pl4vniguor 172.25.6.2:2377
[root@server2 ~]# docker service ps webcluster
部署swarm监控
https://github.com/dockersamples/docker-swarm-visualizer
[root@server1 harbor]# docker pull dockersamples/visualizer:stable
[root@server1 harbor]# docker tag dockersamples/visualizer:stable reg.westos.org/library/visualizer:latest
[root@server1 harbor]# docker push reg.westos.org/library/visualizer:latest
[root@server2 ~]# docker service create \
> --name=viz \
> --publish=8080:8080/tcp \
> --constraint=node.role==manager \
> --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
> visualizer

访问http://172.25.6.2:8080/

关闭sercer3的服务
[root@server3 docker]# systemctl stop docker.service
可以看到高可用副本转移到server4中

滚动更新
[root@server2 ~]# docker service rm webcluster
[root@server1 harbor]# docker pull ikubernetes/myapp:v1
[root@server1 harbor]# docker pull ikubernetes/myapp:v2
[root@server1 harbor]# docker tag ikubernetes/myapp:v1 reg.westos.org/library/myapp:v1
[root@server1 harbor]# docker tag ikubernetes/myapp:v2 reg.westos.org/library/myapp:v2
[root@server1 harbor]# docker push reg.westos.org/library/myapp:v1
[root@server1 harbor]# docker push reg.westos.org/library/myapp:v2
[root@server2 ~]# docker service create --name webcluster -p 80:80 --replicas 3 myapp:v1
[root@server2 ~]# docker service scale webcluster=10
[root@server2 ~]# docker service update --image myapp:v2 --update-parallelism 2 --update-delay 5s webcluster

用脚本更新
[root@server2 ~]# docker service rm webcluster
version: "3.9"
services:
webcluster:
image: myapp:v1
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 2
delay: 5s
restart_policy:
condition: on-failure
~
[root@server2 ~]# docker stack deploy web -c webcluster.yml
改成版本2



node.role == manager指定这个service的实例均运行在swarm manager节点上,不会分到worker节点
visualizer:
image: visualizer
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints:
- "node.role==manager"
[root@server2 ~]# vim webcluster.yml
[root@server2 ~]# docker stack deploy web -c webcluster.yml
Updating service web_webcluster (id: jn9m5q6ob3p8kcrkds7mvrcpi)
Creating service web_visualizer
[root@server2 ~]# docker stack ls
NAME SERVICES ORCHESTRATOR
web 2 Swarm
[root@server2 ~]# docker stack ps web

本文详细介绍了Docker镜像的下载、安装、分层结构及构建,强调了Dockerfile的使用和镜像优化。此外,还探讨了私有仓库的建立、镜像加速器配置、企业级仓库Harbor的构建,以及Docker网络配置。在安全方面,讨论了容器资源控制、安全加固策略和Docker安全工具。最后,简述了Docker Machine、Docker Compose和Docker Swarm在集群管理中的作用。
491

被折叠的 条评论
为什么被折叠?



