docker容器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker容器相关的知识,希望对你有一定的参考价值。
1. Docker安装如果是在centos上安装docker,建议在7系列上安装。
安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2
添加Docker软件包源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装Docker CE
yum install docker-ce -y
启动
systemctl start docker
开机启动
systemctl enable docker
查看Docker信息
docker info
配置docker加速器
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh|sh -s http://bc437cce.m.daocloud.io
Docker默认连接的国外官方镜像,通常根据网络情况不同,访问时快时慢,大多时候获取速度非常慢,为了提升效率可以自建仓库或者修改为国内仓库源,提高拉取镜像的速度。
vim /etc/docker/daemon.json
"registry-mirrors": ["https://pee6w651.mirror.aliyuncs.com"]
systemctl restart docker
2. docker管理
2.1 创建一个nginx容器,并放入后台运行
docker container run -d nginx
2.2 列出当前正在运行的容器
docker container ls
指定容器名称、主机名和设置环境变量
docker container run -d --name nginx01 -e TEST=123 -h nginx01 nginx
2.3 进入容器查看
docker container exec -it nginx01 bash
root@nginx01:/# echo $TEST
123
root@nginx01:/# hostname
nginx01
2.4 让用户访问容器
docker container run -d --name nginx02 -p 88:80 nginx
[root@salt-master ~]# netstat -tnlp|grep 88
tcp6 0 0 :::88 :::* LISTEN 23224/docker-proxy
浏览器访问如下
2.5 容器资源管理
容器是密集型的,启动大量容器,如果不对容器进行资源限制,难免会因为某个容器占用大量资源,导致宿主机资源耗尽。资源限制常用选项。
执行docker run命令时能使用的和内存限制相关的所有选项如下
选项 描述
-m,--memory 内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M
--memory-swap 允许交换到磁盘中的内存量
--memory-swappiness 容器使用SWAP分区交换的百分比。(0-100,默认为-1
--oom-kill-disable 是否阻止 OOM killer kill掉容器,默认没设置
--oom-score-adj 容器被 OOM killer kill的优先级,范围是[-1000, 1000],默认为 0
--kernel-memory 核心内存限制。格式同上,最小为 4M
--cpuset-cpus="" 允许使用的 CPU 集,值可以为 0-3,0,1
--cpus 可以使用的cpu数量
限制容器内存使用
docker container run -d --name nginx03 --memory=‘100m‘ --memory-swap=‘100m‘ --oom-kill-disable nginx
查看当前容器内存限制及使用
[root@salt-master ~]# docker stats --no-stream nginx03
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
01fde633ae01 nginx03 0.00% 3.691MiB / 100MiB 3.69% 648B / 0B 2.1MB / 0B 2
cpu限额
允许容器最多使用50%的cpu
[root@salt-master ~]# docker container run -d --name nginx04 --cpus=".5" nginx
建议:设置memory再禁用oom killer,cpu使用不超过50%。
3. 生产环境常用docker命令汇总
3.1 docker info
显示 Docker 系统信息,包括镜像和容器数。
docker version 显示docker版本信息
3.2 Docker pull
从docker仓库中下载镜像
如docker pull docker.io/nginx
3.3 Docker run
基于docker run启动nginx镜像,并且启动到/bin/bash解释器;
docker run -itd docker.io/nginx /bin/bash
-i表示:interactive交互;
-t表示:tty终端;
d表示:daemon后台启动;
基于docker run启动nginx镜像,启动到/bin/bash解释器,同时映射本地80端口至容器80端口;
docker run -p 80:80 -itd docker.io/nginx /bin/bash
-p端口映射,第一个80宿主机监听端口,第二个80端口为容器监听;
浏览器输入宿主机IP+80端口,即可访问容器中的80端口所在服务
3.4 Docker images
查看已下载的本地docker镜像列表
3.5 Docker ps
查看当前正在运行中的容器,docker ps -a 查看当前Linux系统所有容器,包括运行和已经停止、其他容器(所有容器)
3.6 Docker search
从docker仓库中搜索镜像
如docker search nginx docker search tomcat
3.7 docker inspect
docker inspect 容器ID 查看容器详细信息
- docker exec
进入docker容器操作相关命令
如在Docker中容器运行指令:df -h
[root@salt-master ~]# docker exec 1c1d2d958de9 df -h
Filesystem Size Used Avail Use% Mounted on
overlay 17G 7.5G 9.6G 44% /
tmpfs 64M 0 64M 0% /dev
tmpfs 493M 0 493M 0% /sys/fs/cgroup
/dev/mapper/cl-root 17G 7.5G 9.6G 44% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 493M 0 493M 0% /proc/acpi
tmpfs 493M 0 493M 0% /proc/scsi
tmpfs 493M 0 493M 0% /sys/firmware
docker exec -it 1c1d2d958de9 /bin/bash 进入容器进行交互
3.8 docker kill
kill掉正在运行中的某个容器
docker kill 1c1d2d958de9
3.9 docker rm
删除某个指定的已经停止Docker容器,加上-f参数表示强制删除某个指定的正在运行中的Docker容器
3.10 docker rmi
从Docker images列表中删除某个镜像
还有其他一些命令,如下:
docker push 推送指定镜像或者库镜像至docker源服务器
docker history 展示一个镜像形成历史
docker attach 当前shell下attach连接指定运行镜像
docker build 通过Dockerfile定制镜像,如docker build .
docker commit 提交当前容器为新的镜像
docker cp 从容器中拷贝指定文件或者目录到宿主机中
docker create 创建一个新的容器,同run,但不启动容器
docker diff 查看docker容器变化
docker events 从docker服务获取容器实时事件
docker export 导出容器的内容流作为一个tar归档文件[对应import]
docker import 从tar包中的内容创建一个新的文件系统映像[对应export]
docker load 从一个tar包中加载一个镜像[对应save]
docker login 注册或者登陆一个docker源服务器
docker logout Dockerregistry退出
docker logs 输出当前容器日志信息
docker port 查看映射端口对应的容器内部源端口
docker pause 暂停容器
docker restart 重启运行的容器
docker save 保存一个镜像为一个tar包[对应load]
docker tag 给源中镜像打标签
docker top 查看容器中运行的进程信息
docker unpause 取消暂停容器
docker wait 截取容器停止时的退出状态值
4. Docker镜像原理剖析
完整的Docker镜像可以支撑一个Docker容器的运行,在Docker容器运行过程中主要提供文件系统数据支撑。Docker镜像是分层结构的,是由多个层级组成,每个层级分别存储各种软件实现某个功能,Docker镜像作为Docker中最基本的概念,有以下几个特性:
1)镜像是分层的,每个镜像都由一个或多个镜像层组成;
2)可通过在某个镜像加上一定的镜像层得到新镜像;
3)通过编写Dockerfile或基于容器Commit实现镜像制作;
4)每个镜像层拥有唯一镜像ID,Docker引擎默认通过镜像ID来识别镜像;
5)镜像在存储和使用时,共享相同的镜像层,在PULL镜像时,已有的镜像层会自动跳过下载;
6)每个镜像层都是只读,即使启动成容器,也无法对其真正的修改,修改只会作用于最上层的容器层。
如图所示为一个完整的Docker容器系统,可以看出:
Docker容器是一个或多个运行进程,而这些运行进程将占有相应的内存,相应的CPU计算资源,相应的虚拟网络设备以及相应的文件系统资源。Docker容器所占用的文件系统资源,则通过Docker镜像的镜像层文件来提供。基于每个镜像的Json文件,可以通过解析Docker镜像的json的文件,获知应该在这个镜像之上运行什么样的进程,应该为进程配置什么样的环境变量,而Docker守护进程实现了从静态向动态的转变。
Docker虚拟化引也是一个C/S(Client/Server)结构的应用,如图所示
该图为Docker虚拟化完整体系结构图,包括如下各个组件:
1)Docker Server是一个常驻进程;
2)REST API 实现了client和server间的交互协议;
3)Docker CLI 实现容器和镜像的管理,为用户提供统一的操作界面;
4)Images为容器提供了统一的软件、文件底层存储;
5)Container是Docker虚拟化的产物,直接作为生产使用;
6)Network为Docker容器提供完整网络通信;
7)Volume为Docker容器提供额外磁盘、文件存储对象。
5. Dockerfile镜像管理及优化最佳实践
官方仓库虽然有数十万计的免费镜像,但无法满足公司业务需求,这就需要我们自己去构建镜像。
Docker可以通过Dockerfile自动构建镜像,Dockerfile是一个文本文档,其中包含了用户在命令行上所有命令来组合镜像。使用docker build自动构建。
官方文档:https://docs.docker.com/engine/reference/builder/
Docker通过从一个Dockerfile包含所有命令的文本文件中读取指定来自动构建镜像,这些命令按顺序构建给定镜像。一个Dockerfile遵循特定的格式和指令集,常用指令集如下:
5.1 构建nginx基础镜像
编写Dockerfile文件,Dockerfile-nginx 内容如下
FROM centos:7
MAINTAINER https://blog.51cto.com/tuwei
RUN yum install -y gcc gcc-c++ make \
openssl-devel pcre-devel gd-devel libxslt-devel \
iproute net-tools telnet wget curl && \
yum clean all && \
rm -rf /var/cache/yum/
RUN wget http://nginx.org/download/nginx-1.14.2.tar.gz && tar xf nginx-1.14.2.tar.gz && cd nginx-1.14.2 && ./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_module && \
make -j 4 && make install && \
mkdir -p /usr/local/nginx/conf/vhost && \
rm -rf /usr/local/nginx/html/ && \
echo "ok" >/usr/local/nginx/html/status.html && \
rm -rf ../nginx-1.14.2
ENV PATH $PATH:/usr/local/nginx/sbin
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建 docker build -t nginx-114 -f Dockerfile-nginx .
5.2 构建php镜像
Dockerfile-php内容如下
FROM centos:7
MAINTAINER https://blog.51cto.com/tuwei
RUN yum install epel-release -y && \
yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
libcurl-devel libjpeg-devel libpng-devel openssl-devel \
libmcrypt-devel libxslt-devel libtidy-devel autoconf \
iproute net-tools telnet wget curl && \
yum clean all && \
rm -rf /var/cache/yum/
RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
tar zxf php-5.6.36.tar.gz && \
cd php-5.6.36 && \
./configure --prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-config-file-scan-dir=/usr/local/php/etc/php.d \
--enable-fpm --enable-opcache --enable-static=no \
--with-mysql --with-mysqli --with-pdo-mysql \
--enable-phar --with-pear --enable-session \
--enable-sysvshm --with-tidy --with-openssl \
--with-zlib --with-curl --with-gd --enable-bcmath \
--with-jpeg-dir --with-png-dir --with-freetype-dir \
--with-iconv --enable-posix --enable-zip \
--enable-mbstring --with-mhash --with-mcrypt --enable-hash \
--enable-xml --enable-libxml --enable-debug=no && \
make -j 4 && make install && \
cp php.ini-production /usr/local/php/etc/php.ini && \
cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf && \
sed -i "90a \daemonize = no" /usr/local/php/etc/php-fpm.conf && \
mkdir /usr/local/php/log && \
rm -rf ../php*
ENV PATH $PATH:/usr/local/php/sbin
WORKDIR /usr/local/php
EXPOSE 9000
CMD ["php-fpm"]
构建
docker build -t php-56 -f Dockerfile-php .
5.3 项目镜像
有了基础镜像,就可以封装项目到新的镜像。
[root@localhost project]# cat Dockerfile-nginx
FROM nginx-114
COPY nginx.conf /usr/local/nginx/conf/
[root@localhost project]# cat Dockerfile-php
FROM php-56
COPY wwwroot /wwwroot
CMD ["php-fpm"]
Nginx配置文件。增加对php的处理
[root@localhost project]# cat nginx.conf
user nobody;
worker_processes 1;
error_log logs/error.log info;
events
worker_connections 1024;
http
include mime.types;
default_type application/octet-stream;
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" ‘
‘$status $body_bytes_sent "$http_referer" ‘
‘"$http_user_agent" "$http_x_forwarded_for"‘;
sendfile on;
keepalive_timeout 65;
server
listen 80;
server_name localhost;
access_log logs/host.access.log main;
location /
root html;
index index.html index.htm;
location ~ .php$
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
部署:
docker network create lnmp
docker volume create wwwroot
docker container run -d --name lnmp_nginx -p 88:80 --net lnmp --mount src=wwwroot,dst=/usr/local/nginx/html nginx:v1
docker container run -d --name lnmp_php --net container:lnmp_nginx --mount src=wwwroot,dst=/usr/local/nginx/html php:v1
创建PHP容器时指定与Nginx容器同一个网络,这样Nginx就可以代理127.0.0.1:9000到PHP-FPM了。
5.5 编写Dockerfile最佳实践
5.5.1 减少镜像层
一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层。
5.5.2 优化镜像大小:清理无用数据
一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。
5.5.3 减少网络传输时间
最好在内部有一个存放软件包的地方,类似于上述的PHP官方下载地址,如果用到maven构建这样的操作,同时也更改为私有maven仓库,减少网络传输时间,提高镜像构建速度。
5.5.4 多阶段镜像构建
如果运行一个项目,根据咱们上面的做法,是直接把代码拷贝到基础镜像里,如果是一个需要预先代码编译的项目呢?例如JAVA语言,如何代码编译、部署在一起完成呢!
上面做法需要事先在一个Dockerfile构建一个基础镜像,包括项目运行时环境及依赖库,再写一个Dockerfile将项目拷贝到运行环境中,有点略显复杂了。
像JAVA这类语言如果代码编译是在Dockerfile里操作,还需要把源代码构建进去,但实际运行时只需要构建出的包,这种把源代码放进去有一定安全风险,并且也增加了镜像体积。
为了解决上述问题,Docker 17.05开始支持多阶段构建(multi-stage builds),可以简化Dockerfile,减少镜像大小。
例如,构建JAVA项目镜像:
git clone https://github.com/b3log/solo.git
cd solo
vi Dockerfile
FROM maven AS build
ADD ./pom.xml pom.xml
ADD ./src src/
RUN mvn clean package
FROM tomcat-85
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war
CMD ["catalina.sh", "run"]
构建 docker build -t solo:v1 -f Dockerfile-solo .
docker container run -d -v /usr/local/jdk1.8:/usr/local/jdk solo:v1
首先,第一个FROM 后边多了个 AS 关键字,可以给这个阶段起个名字。
然后,第二部分FROM用的我们上面构建的Tomcat镜像,COPY关键字增加了--from参数,用于拷贝某个阶段的文件到当前阶段。这样一个Dockerfile就都搞定了。
小结:镜像小有很多好处,例如快速部署、快速回滚。减少服务中断时间,同时镜像仓库占用磁盘空间也少了。
6. 企业私有仓库搭建harbor
构建Docker仓库方式除了使用Registry之外,还可以使用Harbor。
如下为Registry方式缺点:
- 缺少认证机制,任何人都可以随意拉取及上传镜像,安全性缺失;
- 缺乏镜像清理机制,镜像可以push却不能删除,日积月累,占用空间会越来越大;
- 缺乏相应的扩展机制;
鉴于以上缺点,我们通常在生产环境中,不会直接使用docker registry来实现提供镜像服务。
6.1 harbor简介
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。
作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry中,确保数据和知识产权在公司内部网络中管控。另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。
6.2 Harbor仓库部署
Harbor仓库部署两种方式,一种是off-line ,一种是on-line,即离线和在线安装,此处选择离线安装。
6.2.1 安装Docker-Compose快速编排工具
yum install epel-release –y
yum install python-pip –y
pip install --upgrade pip
pip install docker-compose
6.2.2 下载Habor并且解压安装
网上下载离线安装包,解压后修改Habor配置文件harbor.cfg,修改hostname为本机IP地址,然后运行脚本进行安装。
其他docker客户端需要上传镜像到harbor仓库,需要修改docker仓库源为harbor地址。
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=192.168.56.134 添加的地址为harbor地址。然后重启docker服务。
harbor仓库搭建好后,可以创建项目,注册成员。其他docker客户端可以登录harbor仓库。
如docker login 192.168.56.134/library,如需要上传镜像到harbor仓库,登录后将镜像格式进行修改,例如:
docker tag centos:7 192.168.56.134/library/centos:7
push该镜像到harbor仓库
docker push 192.168.56.134/library/centos:7
查看harbor仓库:
企业生产环境一般是利用jenkins拉取代码然后打包成docker镜像并上传到harbor仓库,然后从harbor拉取镜像部署到实际环境
以上是关于docker容器的主要内容,如果未能解决你的问题,请参考以下文章