Docker安装&镜像优化

Docker安装&镜像优化

  • docker安装
  • docker镜像&容器
      • docker commit 构建镜像
      • Dockerfile
      • 镜像的优化-部署nginx
  • docker容器运行
      • 运行容器
      • 进入容器的方法
  • Docker镜像仓库
      • DockerHub
      • registry工作原理
      • 配置镜像加速
      • 搭建私有仓库(搭建本地registry)
      • 为docker仓库添加证书加密功能
      • 添加客户端的push认证
      • 远程主机连接
      • 添加web页面
      • docker-compose的部署
      • Harbor的搭建

需要使用红帽7.5版本以上的镜像构建的虚拟机

docker安装

 阿里云开源镜像站:https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/
 官方站点:https://docs.docker.com/ https://docs.docker.com/install/linux/docker-ce/centos/

安装

yum install bash-* -y
yum install *.rpm

Docker安装&镜像优化_第1张图片

安装完docker后如果 发现tab命令不能补全 是因为缺少一个包 yum install bash-* -y

安装一个小游戏

docker load -i game2048.tar 
docker run -d --name game1 -p 80:80 game2048
docker ps
在浏览器中测试:ip地址 eg:网页游戏

解决“警告”问题:

docker info
可以看到
WARNING: IPv4 forwarding is disabled
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

cd /etc/sysctl.d
 过滤内核参数 将这些改成 1
sysctl -a | grep forwarding
sysctl -a | grep bridge

cd /etc/sysctl.d/
vim docker.conf
inet.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.all.mc_forwarding = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.default.mc_forwarding = 1
net.ipv4.conf.docker0.forwarding = 1
net.ipv4.conf.docker0.mc_forwarding = 1
net.ipv4.conf.eth0.forwarding = 1
net.ipv4.conf.eth0.mc_forwarding = 1
net.ipv4.conf.lo.forwarding = 1
net.ipv4.conf.lo.mc_forwarding = 1
net.bridge.bridge-nf-call-ip6tables = 1

sysctl --system #使其立即生效
docker命令
docker load -i ubuntu.tar 导入镜像(以ubuntu镜像为模板)
docker run -it --name vm1 ubuntu 创建容器(以ubuntu镜像为模板)
docker ps 查看容器状态,当前活跃的
docker ps -a 查看容器状态(包括不活跃的容器),所有的
docker attach vm1 连接容器
docker top vm1 查看容器进程
docker logs vm1 查看容器指令输出 -f 参数可以实时查看
docker inspect vm1 查看容器详情
docker stats vm1 查看容器资源使用率
docker diff vm1 查看容器修改
docker stop vm1 停止容器
docker start vm1 启动容器
docker kill vm1 强制干掉容器
docker restart vm1 重启容器
docker pause/unpause vm1 暂停/恢复容器
docker rm vm1 删除容器
docker rm -f vm1 强制删除容器
docker rmi ubantu 删除镜像
docker images 列出镜像
docker run 参数
-a stdin 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
-d 后台运行容器,并返回容器ID;
-i 以交互模式运行容器,通常与 -t 同时使用;
-P 随机端口映射,容器内部端口随机映射到主机的端口
-p 指定端口映射,格式为:主机(宿主)端口:容器端口
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
–name=“nginx-lb” 为容器指定一个名称;
–dns 8.8.8.8 指定容器使用的DNS服务器,默认和宿主一致;
–dns-search example.com 指定容器DNS搜索域名,默认和宿主一致;
-h “mars” 指定容器的hostname;
-e username=“ritchie” 设置环境变量;
–env-file=[] 从指定文件读入环境变量;
–cpuset=“0-2” or --cpuset=“0,1,2” 绑定容器到指定CPU运行;
-m 设置容器使用内存最大值;
–net=“bridge” 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
–link=[] 添加链接到另一个容器;
–expose=[] 开放一个端口或一组端口;
–volume , -v 绑定一个卷

docker镜像&容器

镜像是一种文件结构,包含如何运行容器的元数据 Dockerfile中的每条命令都会在文件系统中创建一个新的层次结构
文件系统在这些层次上构建起来,镜像就构建于这些联合的文件系统之上 当容器启动后,所有镜像都会统一合并到一个进程中
联合文件系统中的文件被删除时, 它们只是被标记为已删除,但实际上仍然存在
镜像是docker容器的基石,容器是镜像的运行实例,有了镜像才能启动容器

docker images rhel7
docker run -it --name vm1 ubuntu #run:创建并运行一个容器 
-it:以交互式的形式 --name:给容器起个名字 ubuntu:镜像名称
docker ps -a  查看镜像
docker rm b16f9eaab99e  删除镜像,后面加镜像ID

docker commit 构建镜像

运行容器
修改容器
将容器保存为新的镜像

缺点
效率低 可重复性弱 容易出错 使
用者无法对镜像进行审计,存在安全隐患

docker images
docker history ubuntu:latest  # 保存每一层的镜像修改

的意思是 这些操作不是在本机操作的 所有找不到 这并没有什么关系

docker run -it --name test busybox
echo helloworld >testfile
ls
cat testfile 
helloworld
exit #退出并停止运行 ctrl p+q 退出不停止运行
docker ps -a  #注意:我们只是退出了运行中的容器 并没有删除它
docker start test #我们将在后台保存的容器运行起来
docker attach test #此命令可以进入在后台运行起来的容器
docker commit test test:v1  #将我们所修改的容器保存
docker images
docker history test:v1  #我们可以看到 相同的底层是共享的
docker rm 6789012d8958   可以强制删除正在运行中的容器

缺点是:无法得知对这个容器到底做了什么操作 虽然它已经被保存了,新运行的容器也有之前所保存的数据

Dockerfile

dockerfile语法

FROM 每个Dockerfile的第一条指令都应该是FROM。FROM指令指定一个已经存在的镜像,后续指令都是将基于该镜像进行,这个镜像被称为基础镜像(base iamge)。在这里ubuntu:latest就是作为新镜像的基础镜像。也就是说Dockerfile构建的新镜像将以ubuntu:latest操作系统为基础。在运行一个容器时,必须要指明是基于哪个基础镜像在进行构建。
MAINTAINER MAINTAINER指令,这条指令会告诉Docker该镜像的作者是谁,以及作者的邮箱地址。这有助于表示镜像的所有者和联系方式
RUN 在这些命令之后,RUN指令会在当前镜像中运行指定的命令。这里我们通过RUN指令更新了APT仓库,安装nginx包,并创建了一个index.html文件。像前面说的那样,每条RUN指令都会创建一个新的镜像层,如果该指令执行成功,就会将此镜像层提交,之后继续执行Dockerfile中的下一个指令。默认情况下,RUN指令会在shell里使用命令包装器/bin/sh -c 来执行。如果是在一个不支持shell的平台上运行或者不希望在shell中运行(比如避免shell字符串篡改),也可以使用exec格式的RUN指令,通过一个数组的方式指定要运行的命令和传递给该命令的每个参数:RUN [“apt-get”, “install”, “-y”, “nginx”]
EXPOSE EXPOSE指令是告诉Docker该容器内的应用程序将会使用容器的指定端口。这并不意味着可以自动访问任意容器运行中服务的端口。出于安全的原因,Docker并不会自动打开该端口,而是需要你在使用docker run运行容器时来指定需要打开哪些端口。可以指定多个EXPOSE指令来向外部公开多个端口,Docker也使用EXPOSE指令来帮助将多个容器链接。
COPY 把文件从build context复制到镜像,支持两种形式:COPY src dest 和 COPY [“src”, “dest”],src必须指定build context中的文件或目录
ADD 用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:ADD html.tar /var/www
ENV 设置环境变量,变量可以被后续的指令使用:ENV HOSTNAME sevrer1.example.com
WORKDIR 为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在会自动创建。
CMD 与 ENTRYPOIN 这两个指令都是用于设置容器启动后执行的命令,但CMD会被docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。docker run后面的参数可以传递给ENTRYPOINT指令当作参数。Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。

注意:一定要创建一个新的目录 因为在构建镜像的时候,会默认把dockerfile所在的目录中的所有目录发送给docker引擎,举个例子
如果你把dockerfile放在/目录下 那么这个过程会变得非常的缓慢

vim dockerfile
FROM busybox  #以哪个基础镜像为模板
RUN echo testfile > file1 #在新镜像中你要执行的哪些动作
RUN echo testfile > file2

docker build -t test:v2 #镜像名称 . #.代表当前目录
docker images
docker history test:v2

再次更改dockerfile 注意:不要随便加空格(要使用缓存 之前内容不能随便更改)

如果我们希望在构建镜像时不使用缓存,可以在docker build命令中加上 --no-cache参数
dockerfile中每一个指令都会创建一个镜像层,上层是依赖于下层的,无论什么时候,只要某一层发生变化, 其上面所有层的缓存都会失败
本质:dockerfile中的每一层其实就是执行了一个docker commit

镜像的优化-部署nginx

选择最经简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去构建缓存
使用多阶段构建镜像

前提:保证镜像存在于本地

编写dockerfile

cat dockerfile 

FROM rhel7
EXPOSE 80
MAINTAINER dd@westos.org
COPY dvd.repo /etc/yum.repos.d/
RUN rpmdb --rebuilddb  
RUN yum install -y gcc make pcre-devel zlib-devel
ADD nginx-1.15.9.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.9
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

其中
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]  通过exec的方式启动nginx
RUN rpmdb --rebuilddb  #重新构建rpm数据库 如不执行这一条命令 会报错 #上课示例的时候可以先不加这一句 


docker build -t nginx:v1 .

查看镜像大小

减少镜像层数------合并多个RUN
删除解压目录------减少中间产物

注意:修改了指令 哪怕是一个空格 缓存就不能用了 。
使用缓存可以加快镜像构建速度

vimdockerfile 

FROM rhel7
EXPOSE 80
MAINTAINER dd@westos.org
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.15.9.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.9
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all && ./configure --prefix=/usr/local/nginx && make && make install && rm -rf /mnt/nginx-1.15.9
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

docker build -t nginx:v2 .
docker images

使用多阶段构建镜像

细看dockerfile 我们其实只需要编译好的nginx的二进制文件

vimdockerfile 

FROM rhel7:latest as build
EXPOSE 80
MAINTAINER dd@westos.org
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.15.9.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.9
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all && ./configure --prefix=/usr/local/nginx && make && make install && rm -rf /mnt/nginx-1.15.9
####以上只是一个桥梁

FROM rhel7:latest #基于rhel7的基础镜像
EXPOSE 80
MAINTAINER dd@westos.org
VOLUME ["/usr/local/nginx/html"]
COPY --from=build /usr/local/nginx /usr/local/nginx #从上一层的构建中拷贝
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
 
docker build -t nginx:v4 . 
docker images

github上有提供的nginx官方镜像
Docker安装&镜像优化_第2张图片

docker容器运行

运行容器

启动容器的方法

docker run ubuntu pwd
docker run ubuntu ls

容器长期运行

因为容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出

docker run ubuntu /bin/bash -c 'while true;do sleep 1;done'

#while语句让bash不会退出,可以打开另一个终端查看容器的状态

通过while启动的容器虽然能够保持运行,但实际上没有干什么有意义的事情,容器常见的用途是运行后台服务

docker run --name "my_http_server" -d httpd  指定容器的名字

进入容器的方法

我们经常需要进入到容器里去做一些工作,比如查看日志,调式,启动其他进程等,有两种方法进入容器:

attach

通过docker attach可以attach到容器启动命令的终端

docker attach 039c0b492b5da9301d576b0d7db269545d0289cf31f5706d575e708258b20502

exec

docker run -d rhel7-up /bin/bash -c "while true; do sleep1;echo I_am_in_container;done"
docker exec -it c72e8ee26615ca661093d6114c0dbb143e50ef423382730d0f3d8a92d01b2e0c bash
yum install procps-ng-3.3.10-10.el7.x86_64 -y
ps -elf    

attach与exec主要的区别

1.attach直接进入容器启动命令的终端,不会启动新的进程
2.exec则是在容器中打开新的终端,并且可以启动新的进程
3.如果想直接在终端中查看启动命令的输入,用attach,其他情况使用exec

按用途容器大致可分为两类:服务类容器和工具类容器 服务类容器以daemon的形式运行,对外提供服务,比如web server,数据库等,通过-d以后台方式启动这类容器是非常合适的,如果要排查问题,可以通过exec -it进入容器
工具类容器通常能给我们提供一个临时的工作环境,通常以run -it方式运行

Docker镜像仓库

仓库的概念

docker仓库是用来保存镜像的位置,docker提供一个注册服务器(register)来保存多个仓库,每个仓库又可以包含多个具备不同的tag的镜像
docker运行中使用的默认仓库是docker Hub 公共仓库 docker hub:是docker公司维护的公共仓库,用户可以免费使用,也可以购买私有仓库 使用公共registry

DockerHub

保存和分发镜像的最直接的方法就是使用DockerHub

在docker hub上注册一个帐号

登陆

docker login -u dangdangwestos
Password:  #密码:dangdang
cat .docker/config.json #做过一个认证后就把认证信息放在文件中 

修改镜像的名字 使之与Docker Hub帐号匹配

docker hub为了区分不同用户的镜像名 镜像的名字中要包含用户名
完整格式为[username]/xxx:tag

镜像的上传和拉取

docker search busybox搜寻docker官方仓库中的镜像
docker tag busybox:latest dangdangwestos/busybox:latest  打标签
docker push dangdangwestos/busybox:latest  上传
docker pull dangdangwestos/busybox:latest   拉取 会先检索本地的镜像 如果存在则不会被拉取,如果有,先删除之前的再拉取
docker tag dangdangwestos/busybox:latest busybox:latest  再次打标签简化镜像名称
删除docker hub上的镜像

registry工作原理

用户要获取并下载镜像
Docker安装&镜像优化_第3张图片

用户发送请求到index来下载镜像。
index 响应返回三个相关部分信息:该镜像位于的registry+该镜像包括所有层的校验+以授权目的Token
用户通过响应中返回的Token和registry沟通,registry全权负责镜像,它存储基本的镜像和继承的层。
registry现在要与index证实该token是被授权的。
index会发送“true” 或者 “false”给registry,由此允许用户下载所需要的镜像。

用户要上传镜像到registry中

Docker安装&镜像优化_第4张图片

用户发送带证书请求到index要求分配库名。
在成功认证,命名空间可用以及库名被分配之后。index响应返回临时的token。
镜像连带token,一起被推送到registry中。
registry与index证实token,然后在index验证之后开始读取推送流。
该index然后更新由Docker生成的镜像校验。

用户要从index或registry中删除镜像
Docker安装&镜像优化_第5张图片

index接收来自Docker一个删除库的信号。
如果index验证库成功,它将删除该库,并返回一个临时token。
registry现在接收到带有该token的删除信号。
registry与index核实该token,然后删除库以及所有相关信息。
Docker现在通知有关删除的index,然后index移除库的所有记录。

配置镜像加速

搭建私有仓库(搭建本地registry)

docker hub虽然方便 但还是有些限制,
1.需要连接internet,下载和上传速度慢
2.上传到docker hub的镜像任何人都能访问
3.因安全原因很多组织不允许将镜像放到外网

解决方案就是搭建本地的registry docker已经将registry开源了,同时在docker hub上也有官方的镜像registry

拉取仓库的镜像运行

docker search registry
docker pull registry #拉取最新版
docker images
docker history registry
docker run -d --name registry -p 5000:5000 registry #端口映射到本机 便于外部访问
docker inspect 查看镜像信息
docker ps
netstat -antlpe 查看端口是否开启

上传,查看本地仓库的挂载目录

docker tag nginx:v1 localhost:5000/nginx:v1
docker push localhost:5000/nginx
docker inspect 查看镜像信息
cd /var/lib/docker/volumes/37e8aed215b0812c9ca3f3b6018a52bec0029844a2cd7dd4a505a6772fbc7e52/_data/docker/registry/
tree .

以上操作有安全问题(没有认证)和使用的问题(localhost 如果不是本机就使用不了localhost)

作为企业级的私有仓库是远远不够的

为docker仓库添加证书加密功能

官方文档
https://docs.docker.com/registry/insecure/

生成一个自签名证书
mkdir -p certs
openssl req \
> -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key \
> -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) []:westos.org
Email Address []:root@westos.org

ls certs/

重新搭建私有仓库

https://docs.docker.com/registry/deploying/#get-a-certificate

注意此处:REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key -p 443:443 registry
不是:/root/

docker rm -f registry  删除之前运行的registry容器


docker run -d --restart=always   --name registry #容器自启动(docker引擎启动的同时会启动容器)
-v "$(pwd)"/certs:/certs #本地的certs目录挂接到容器的certs目录
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 #-e 编辑 监听本机443的加密端口
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt #证书
-e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key #私钥
-p 443:443 registry

netstat -antlp   开启了443端口

注意:此时 docker的server端已经跑起来了 那么们的本地要去做Tls连接的话也是需要加密证书的

因为我们所使用的域名是westos.org 所以主机名要有解析

ping westos.org
cd /etc/docker/
mkdir -p certs.d/westos.org
cd certs.d/westos.org
cp /root/certs/westos.org.crt ca.crt


docker tag nginx:v3 westos.org/nginx:v3
docker push westos.org/nginx

添加客户端的push认证

在之前的443更改 不用官网的5000 , 之前的registry要删除

mkdir ~/auth
docker run --rm entrypoint htpasswd registry -Bbn admin westos >auth/htpasswd
docker run --rm entrypoint htpasswd registry -Bbn redhat redhat >>auth/htpasswd  多个用户名可追加

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 -p 443:443 -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
docker ps -a
docker login westos.org
Username: admin
Password: 

docker logout westos.org #退出登陆  
push提示报错:Removing login credentials for westos.org

docker push westos.org/nginx
docker login westos.org 

docker push westos.org/nginx:v3 
      no basic auth credentials  提示我们没有认证

docker login westos.org  重新登录
docker push westos.org/nginx:v3 

远程主机连接

准备另一台虚拟机,安装docker并启动 ,主机名要有解析

要有认证文件,这个文件可以从上一台主机获得 现有证书才能完成认证

scp -r certs.d/ server2:/etc/docker/
docker login westos.org  先认证再拉取
docker pull westos.org/nginx:v3

docker run -d --name nginx -p 80:80 westos.org/nginx:v3 测试运行
docker ps
curl localhost

添加web页面

拉取web镜像

去git hub搜索 按照文档做操作 https://github.com/mkuchin/docker-registry-web

docker pull hyper/docker-registry-web
cat .docker/config.json 查看之前的认证信息
docker run -it -p 8080:8080 --name registry-web --link registry:westos.org -e REGISTRY_URL=https://westos.org/v2 -e REGISTRY_TRUST_ANY_SSL=true -e REGISTRY_BASIC_AUTH="YWRtaW46d2VzdG9z" -e REGISTRY_NAME=westos.org:443 hyper/docker-registry-web  #v2:是一个版本

http://172.25.0.3:8080/

推荐学习:https://goharbor.io/ https://docs.docker.com/compose/install/

docker-compose的部署

下载,授予执行权限

 curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version

Harbor的搭建

tar zxf harbor-online-installer-v1.8.2.tgz 
cd harbor/

修改配置文件

vim harbor.yml 
hostname: westos.org
13 https:
14 #   # https port for harbor, default is 443
15    port: 443
16 #   # The path of cert and key files for nginx
17    certificate: /root/certs/westos.org.crt
18    private_key: /root/certs/westos.org.key

27 harbor_admin_password: westos
28 
29 # Harbor DB configuration
30 database:
31   # The password for the root user of Harbor DB. Change this be    fore any production use.
32   password: westos
./prepare   更新配置文件
./install.sh 
docker ps -a
docker-compose ps
docker login westos.org
docker tag rhel7:latest westos.org/library/rhel7

在真机做好解析,浏览器中访问https://westos.org/

这里一定要注意的是:tag的修改 必须加项目名称 而这个项目名称可以自己在网页中创建 docker push westos.org/library/rhel7

你可能感兴趣的:(Linux企业运维)