简介
Docker是管理容器的引擎。
Docker为应用打包、部署平台,而非单纯的虚拟化技术
1.配置docker
1.1搭建docker仓库
准备一台虚拟机server5:
配置软件仓库,从官网下载的仓库!
[root@server5 ~]# cd /etc/yum.repos.d/
[root@server5 yum.repos.d]# vim docker.repo
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/
gpgcheck=0
下载过程中会出现很多的依赖性,这些依赖性都可以从centos源找到,这里我们需从阿里云镜像站搭建一个centos源。
[root@server5 yum.repos.d]# vim CentOS-Base.repo
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-7 - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-7 - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-7 - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-7 - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#contrib - packages by Centos Users
[contrib]
name=CentOS-7 - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/7/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
1.2下载docker-ce
yum install -y docker-ce
开启服务,并开机自启
systemctl enable --now docker
查看docker 信息
docker info
若使用docker info 出现警告iptables的情况的话
解决方式:
vim /etc/sysctl.ddocker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
sysctl --system 刷新
ip addr
1.3测试
若虚拟机连不上网 则在真机:
[root@foundation76 Desktop]# iptables -t nat -I POSTROUTING -s
172.25.76.0/24 -j MASQUERADE
#伪装查看
[root@server5 yum.repos.d]# docker search yakexi007
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
yakexi007/game2048 0
yakexi007/mario 0
yakexi007/nginx 0
[root@server5 ~]# docker load -i game2048 ##本地加载
[root@server5 yum.repos.d]# 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@server5 yum.repos.d]# docker images 查看
REPOSITORY TAG IMAGE ID CREATED SIZE
yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB
[root@server5 yum.repos.d]# docker run -d --name game2048 -p 80:80 yakexi007/game2048 ###做端口映射 第一个80是宿主机的,第二个对应镜像的端口 -d是打入后台,–name 是给镜像取个名字
0c5d7855caa98cc0c8e3370f24d8d9e0f778217e924b64cdc213887e7683a735
##查询端口连接情况
[root@server5 yum.repos.d]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c5d7855caa9 yakexi007/game2048 “/bin/sh -c 'sed -i …” 6 seconds ago Up 6 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp game2048
docker ps -a ## 查看所有的,包括已经停掉的
测试:
访问docker主机的ip:172.25.76.5
若要玩mario则 前面的步骤与2048 相同
docker run -d --name demo1 -p 8080:8080 mario
其中 端口在 history 查找
成功!
2.镜像的构建(分层)
base镜像提供的是最小的Linux发行版 同一docker主机支持运行多种Linux发行版 采用分层结构的最大好处是:共享资源
上传busybox镜像到docker
docker load -i busybox.tar
开启容器busybox,-i表示交互式,-t表示打开伪终端
docker run -it --name demo busybox
创建file1docker ps -a查看所有进程
发现我们操作的痕迹
启动已有容器 并查看进程
上传新的镜像,源于demo容器 demo:v1
docker commit demo demo:v1
docker images
对比查看两层镜像的分层结构
docker history demo:v1
docker history busybox:latest
多了一步我们操作的层
然后删除v1容器
重启读取v1中的内容 并删掉demo,发现不影响v1容器
docker commit demo demo:v1
docker images
docker stop demo
docker rm demo
docker run -it --name demo demo:v1
docker container attach demo 为 进入以存在的demo容器
文件导入镜像
对比层级结构查看,手动添加的容器没有解释每一层的作用
解决方法:
Dockerfile文件方式导入镜像v2,history可以查看具体内容,容器用busybox
mkdir docker
cd docker/
vim Dockerfile
FROM busybox
RUN echo "lcf"
RUN touch file1
在当前目录文件Dockerfile下创建镜像
docker build -t demo:v1 .
查看导入的镜像,可以查到镜像内容
docker images
docker history demo:v1
可以看到层级操作的具体操作解释
3.Dockerfile详解
FROM
指定base镜像,如果本地不存在会从远程仓库下载。
RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包
MAINTAINER
设置镜像的作者,比如用户邮箱等
COPY
把文件从build context复制到镜像
支持两种形式:COPY src dest 和 COPY [“src”, “dest”]
src必须指定build context中的文件或目录
ADD
用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自
动解压到dest,也可以自动下载URL并拷贝到镜像
ENV
设置环境变量,变量可以被后续的指令使用:
ENV HOSTNAME sevrer1.example.com
EXPOSE
如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80
VOLUME
申明数据卷,通常指定的是应用的数据挂在点:
VOLUME ["/var/www/html"]
WORKDIR
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim
CMD 与 ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。
Shell和exec格式的区别:
FROM busybox
ENV name world
ENTRYPOINT echo "hello, $name"
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面的exec格式不会:
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"]
需要改写成以下形式:
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"]
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数。
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]
看下在运行容器时的区别:
docker run --rm busybox:v1
hello world
#docker run --rm busybox:v1 linux
hello linux
因此推荐使用exec格式书写
4.镜像构建- -nginx
导入rhel7镜像,相当于使用rhel7的内核
docker load -i /root/rhel7.tar
编写Dokcerfile创建镜像
vim Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb
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;"]
通过Dockerfile建立镜像v1,执行命令创建镜像rhel7:v1
docker build -t webserver:v1 .
docker images
拉起容器,进程名为demo,查看进程
docker run -d --name demo2 rhel7:v1
docker ps
查demo进程/容器信息
docker inspect demo
测试访问可访问到nginx主页
curl 172.17.0.2
但是我们的镜像v1的大小346MB 但官方的镜像包只有150M左右 的大小
我们实际生产中,需要docker容器中的镜像越小越好 为了解决此问题
我们如果需要每次加载docker之后不希望保留进程则需要加上参数 --rm
eg: docker run -it --rm demo:v1
若想批量删除掉建立的镜像,使用快捷的指令直接删除
powershell docker rmi `docker images |grep ^demo | awk '{print $3}'`
5.镜像优化
方法:
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去用构建缓存
使用多阶段构建镜像
优化思路:
v2镜像:减少镜像层数,合并所有RUN指令,清理镜像构建的中间产物包括编译好的安装包和缓存/mnt/nginx-1.20.1 /var/cache/*
我们继续编辑文件Dockerfile,编辑结果如下:
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && ./configure --prefix=/usr/local/nginx && make && make install && rm -rf /mnt/nginx-1.20.1 && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
webserver v3 6af940ceb6bc 20 seconds ago 258MB
单阶段镜像最佳优化已经到达极限了 则尽量去构建缓存,使用多阶段构建镜像
即创建 两个from
选择最精简的基础镜像
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.20.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.20.1
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && ./configure --prefix=/usr/local/nginx && make && make install && rm -rf /mnt/nginx-1.20.1 && yum clean all
FROM rhel7
EXPOSE 80
COPY --from=build /usr/local/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
docker build -t rhel7:v4 .
查看压缩后的镜像v4大小
docker images webserver
webserver v4 85fdb89a1acc 25 seconds ago 144MB
继续优化镜像的话选择最精简的基础镜像替换rhel7
我们创建一个新的目录new用来存放新的base的文件
cd docker/new/
docker load -i base-debian10.tar
编写文件Dockerfile
FROM nginx:latest as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG Asia/Shanghai
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 images webserver
测试: curl 172.17.0.2
成功
6.本地仓库搭建
先清理之前实验
[root@server5 ~]# docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
[root@server5 ~]# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
58fdae465aed585b58ad533d348b3364faae2aeb25ef998ddcb9736cf72802e5
Total reclaimed space: 0B
启动本地仓库,端口映射为5000
docker run -d --name registry -p 5000:5000 registry
查看进程是否开启 并查看端口5000是否打开
docker ps
netstat -antlp
将容器中的webserver镜像改名并标记到本地仓库中
docker tag webserver:v1 localhost:5000/webserver:latest
docker push localhost:5000/webserver push上传
上传成功后本地路径中也产生了文件
删除之后,重新加载,之前的内容依然存在
6.1本地容器仓库加密认证
首先创建加密认证的密钥,创建一个目录certs用来保存密钥
创建目录,之后生成密钥!
mkdir -p certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key -x509 -days 365 -out certs/westos.org.crt
注:server hostname这块需要写为reg.westos.org待会需要用!
需要在server5之后加上本地解析。
vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.76.250 foundation76.ilt.example.com
172.25.76.1 server1
172.25.76.2 server2
172.25.76.3 server3
172.25.76.4 server4
172.25.76.5 server5 reg.westos.org
172.25.76.6 server6
172.25.76.7 server7
172.25.76.8 server8
172.25.76.9 server9
172.25.76.10 server10
运行docker容器 (-v 挂载进去)
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
标记重命名nginx并归类到本地reg.westos.org仓库中
然后上传容器:
docker tag nginx:latest reg.westos.org/nginx:latest
docker push reg.westos.org/nginx:latest
发现上传容器的时候,报错了
原因:取不到认证,需要将认证移动到指定目录
解决::
mkdir -p /etc/docker/certs.d/reg.westos.org
cd /etc/docker/certs.d/reg.westos.org/
cp ~/certs/westos.org.crt ca.crt
重新标记上传
docker push reg.westos.org/nginx:latest
成功
但若出现这种错误
则为openssl版本低所致
只需升级openssl版本并重新生成证书时修改参数即可
openssl11 req -newkey rsa:4096 -nodes -sha256 -keyout certs/westosorg.key -addext "subjectAltName = DNS:reg.westos.org" -x509 -days 365 -out certs/westos.org.crt
6.2认证
创建认证目录并进入
mkdir auth/htpasswd -p
需要安装认证的软件
yum install httpd-tools -y
为admin用户和lcf用户添加认证信息和密码
htpasswd -Bc auth/htpasswd admin (-c覆盖)
htpasswd -B auth/htpasswd lcf
删除之前的仓库信息registry,运行容器并查看进程!
docker rm -f registry
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 -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -p 443:443 registry
docker ps
docker push reg.westos.org/nginx:latest
上传文件时有报错
解决:
登陆
[root@server5 ~]# docker login reg.westos.org
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
cat /root/.docker/config.json 登陆信息都在这 下次不需要在登陆
docker push reg.westos.org/nginx:latest 再次上传
成功
7.docker-harbor仓库
先删除registry
docker rm -f registry
7.1软件下载
harbor-offline-installer-v1.10.1.tgz
docker-compose-Linux-x86_64-1.27.0
tar zxf harbor-offline-installer-v1.10.1.tgz
cd harbor/
mv docker-compose-Linux-x86_64-1.27.0 /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
mkdir /data
cp ~/certs/ /data/ -r
[root@server5 harbor]# ls /data/certs/
westos.org.crt westos.org.key
7.2.修改配置信息
vim harbor.yml
5 hostname: reg.westos.org
13 https:
14 # # https port for harbor, default is 443
15 port: 443
17 certificate: /data/certs/westos.org.crt
18 private_key: /data/certs/westos.org.key
27 harbor_admin_password: westos
安装
./install.sh
当出现 ERROR: yaml.parser.ParserError: while parsing a block mapping in
“./docker-peer.yaml”, line 10, column 5 expected , but found ‘’ in
“./docker-peer.yaml”, line 17, column 3 时是空格导致的未对齐(严格意义上的对齐)
安装成功
docker-compose ps (必须在harbor目录下输入命令)
docker ps
7.3.登陆网页
访问172.25.76.5
7.4.添加默认仓库路径
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.westos.org"]
}
查看到新的添加的镜像路径
systemctl reload docker.service
docker info
docker pull nginx
docker rmi nginx:latest 删除nginx后images里没有
docker run -d --name demo nginx
运行容器的时候,pull拉取镜像会自动下载没有的镜像
7.5.获取认证
docker logout reg.westos.org
docker login reg.westos.org
Username: admin
Password:
是登陆web页面的账号密码。
docker tag nginx:latest reg.westos.org/library/nginx:latest
docker push reg.westos.org/library/nginx:latest
网页查看是否上传
7.6重新下载配置
docker-compose down
./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
扫描完成。
启用docker内容信任
export DOCKER_CONTENT_TRUST=1
export DOCKER_CONTENT_TRUST_SERVER=https://reg.westos.org:4443
部署根证书
mkdir ~/.docker/tls/reg.westos.org:4443 -p
cd ~/.docker/tls/reg.westos.org:4443
cp /etc/docker/certs.d/reg.westos.org/ca.crt .
上传之前上传的nginx/library
docker push reg.westos.org/library/nginx:latest
显示已经存在,需要我们输入root key 当我们只修改标签的时候,我们只用输入repository key
Enter passphrase for new root key with ID 72e5409: #根密码
Repeat passphrase for new root key with ID 72e5409:
Enter passphrase for new repository key with ID 3eb6164: ##仓库的key
Repeat passphrase for new repository key with ID 3eb6164:
Finished initializing "reg.westos.org/library/nginx"
Successfully signed reg.westos.org/library/nginx:latest
网页访问 签名成功
我们把镜像的名字更改之后重新拉取镜像v1 只需要更改仓库的key
docker tag nginx:latest reg.westos.org/library/nginx:v1
docker push reg.westos.org/library/nginx:v1
还有一个好处为 本来拉取报错的镜像,现在也可以拉取镜像了
当输入
export DOCKER_CONTENT_TRUST=0
再次拉取的时候就不需要再输入认证了
7.8.优化容器
为了不让扫描使占用的空间越来越大,所以重新修改一下选项
export DOCKER_CONTENT_TRUST=0
cd
docker-compose down
./prepare
./install.sh --with-chartmuseum
阿里云镜像加速器查找方法:
登录阿里云帐号
找到 容器镜像服务 搜索框输入 镜像 找到 容器镜像服务
找到 加速器地址
点镜像加速器 加速器地址 就可以找到操作步骤每个人都有一串不同的代码