docker相当于简化版的虚拟机
docker的安装
Ubuntu的安装(使用ubuntu未使用root权限时,请注意权限问题)
#安装工具
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
#安装证书
curl -fssL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
#写入软件源信息(等同centos的yum源配置)
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
#安装docker
sudo apt-get -y install docker-ce=5:18.09.3~3-0~ubuntu-bionic docker-ce-cli=5:18.09.3~3-0~ubuntu-bionic
systemctl status docker
docker version
注:ubunru如是普通用户请注意权限docker.sock,以下任意一种都可以:
1)加acl权限:sudo setfacl -m u:li:rwx docker.sock
2)修改权限:sudo chmod a+rw /var/run/docker.sock
centos安装docker
安装依赖3个源:
wget -O /etc/yum.repos.d/Docker-Centos-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/Docker-epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
wget -O /etc/yum.repos.d/Docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#列出历史版本的docker
yum search --showduplicates docker
#选出对应版本进行安装
yum install docker-ce-19.03.5-3.el7 docker-ce-cli-19.03.5-3.el7 -y
systemctl enable --now docker
docker version
镜像加速:
阿里加速网址:
https://cr.console.aliyun.com/
我的镜像加速网址:
https://6x29x5w3.mirror.aliyuncs.com
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://6x29x5w3.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
镜像管理:
镜像搜索:
https://hub.docker.com/
下载镜像:docker pull
查看镜像:docker images
镜像导出:sudo docker save nginx:latest > /data/nginx.tar
镜像导入:sudo load < /data/nginx.tar
删除镜像:docker rmi -f feb5d9fea6a5
镜像打标签:docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
容器的基础命令:
运行容器:docker run docker run [选项] [镜像名] [shell命令] [参数]
-i, --interactive Keep STDIN open even if not attached,通常和-t一起使用
-t, --tty 分配pseudo-TTY,通常和-i一起使用,注意对应的容器必须运行shell才支持
-d, --detach Run container in background and print container ID,台后运行,
--name string Assign a name to the container
--h, --hostname string Container host name
--rm Automatically remove the container when it exits
-p, --publish list Publish a container's port(s) to the host
-P, --publish-all Publish all exposed ports to random ports
--dns list Set custom DNS servers
--entrypoint string Overwrite the default ENTRYPOINT of the image
--restart policy
--privileged Give extended privileges to container
-e, --env=[] Set environment variables
--env-file=[] Read in a line delimited file of environment variables
显示当前运行容器:docker ps -aq
显示当前运行容器进程:docker top 【容器ID】
查看容器资源情况:docker stats 61edb5bc4cf9
查看容器资源信息:docker inspect 61edb5bc4cf9
删除容器:
删除所有停止容器:docker container prune -f 或者docker rm `docker ps -qf status=exited`、
删除指定容器:docker rm 2fcff9fab5cf
删除别名:
alias rmex='docker rm `docker ps -qf status=exited`'
alias rmc='docker rm -f `docker ps -q -a`'
容器启动和停止:docker start|stop|restart|pause|unpause 容器ID
进入正在运行的容器:docker exec -it d482ba722dda bash
执行一次性命令:docker exec -it d482ba722dda cat /etc/redhat-release
随机端口映射:docker run -P -d --name nginx111 nginx
容器80端口映射到宿主机81端口:docker run -d -p 81:80 --name nginx222 nginx
查看容器的日志:docker logs
docker镜像制作
制作镜像的方法:
docker commit #通过修改现有容器,将之手动构建为镜像
docker build #通过Dockerfile文件,批量构建为镜像
Dockfile 使用详解
FROM: 指定基础镜像
定制镜像,需要先有一个基础镜像,在这个基础镜像上进行定制。FROM 就是指定基础镜像,此指令通常必需放在Dockerfile文件第一个非注释行。后续的指令都是运行于此基准镜像所提供的运行环境
LABEL: 指定镜像元数据(镜像的说明和标签)
一个镜像可以有多个label ,还可以写在一行中,即多标签写法,可以减少镜像的的大小
RUN: 执行 shell命令
通常各种基础镜像一般都支持丰富的shell命令
注意: RUN 可以写多个,每一个RUN指令都会建立一个镜像层,所以尽可能合并成一条指令,比如将多个shell命令通过 && 连接一起成为在一条指令
每个RUN都是独立运行的,和前一个RUN无关
ENV: 设置环境变量
ENV 可以定义环境变量和值,会被后续指令(如:ENV,ADD,COPY,RUN等)通过$KEY或${KEY}进行引用,并在容器运行时保持
#变量赋值格式
ENV <key1>=<value1> <key2>=<value2> \ #此格式可以支持多个key赋值,定义多个变量建议使用,减少镜像层
#变量支持高级赋值格式
${key:-word}
${kye:+word
COPY: 复制文本
复制本地宿主机的 到容器中的.
必须是build上下文中的路径(为 Dockerfile 所在目录的相对路径),不能是其父目录中的文件
如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制
如果指定了多个, 或在中使用了通配符,则必须是一个目 录,且必须以 / 结尾
如果事先不存在,它将会被自动创建,这包括其父目录路径,即递归创建目录
ADD: 复制和解包文件
该命令可认为是增强版的COPY,不仅支持COPY,还支持自动解缩。可以将复制指定的 到容器中的
CMD: 容器启动命令
一个容器中需要持续运行的进程一般只有一个,CMD 用来指定启动容器时默认执行的一个命令,且其运行结束后,容器也会停止,所以一般CMD 指定的命令为持续运行且为前台命令.
如果docker run没有指定任何的执行命令或者dockerfile里面也没有ENTRYPOINT,那么开启容器时就会使用执行CMD指定的默认的命令
ENTRYPOINT: 入口点
功能类似于CMD,配置容器启动后执行的命令及参数
VOLUME: 匿名卷
在容器中创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等,一般会将宿主机上的目录挂载至VOLUME 指令指定的容器目录。即使容器后期被删除,此宿主机的目录仍会保留,从而实现容器数据的持久保存。
宿主机目录为 /var/lib/docker/volumes/<volume_id>/_data
VOLUME <容器内路径>
VOLUME ["<容器内路径1>", "<容器内路径2>"...]
ARG: 构建参数
EXPOSE: 暴露端口
指定服务端的容器需要对外暴露(监听)的端口号,以实现容器与外部通信。
EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会真正暴露端口,即不会自动在宿主进行端口映射
因此,在启动容器时需要通过 -P 或-p ,Docker 主机才会真正分配一个端口转发到指定暴露的端口才可
注意: 即使 Dockerfile没有EXPOSE 端口指令,也可以通过docker run -p 临时暴露容器内程序真正监
听的端口,所以EXPOSE 相当于指定默认的暴露端口,可以通过docker run -P 进行真正暴露
格式:EXPOSE <port>[/ <protocol>] [<port>[/ <protocol>] ..]
WORKDIR: 指定工作目录
为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录,当容器运行后,进入容器内WORKDIR指定的默认目录
WORKDIR 指定工作目录(或称当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会自行创建
语法:WORKDIR /path/to/workdir
ONBUILD: 子镜像引用父镜像的指令
可以用来配置当构建当前镜像的子镜像时,会自动触发执行的指令,但在当前镜像构建时,并不会执行,即延迟到子镜像构建时才执行
USER: 指定当前用户
范例:RUN groupadd -r mysql && useradd -r -g mysql mysql
HEALTHCHECK: 健康检查
STOPSIGNAL: 退出容器的信号
SHELL : 指定shell
.dockerignore文件(忽略复制至容器中)
docker build命令
-t --tag list #设置注册名称、镜像名称、标签。格式为 <注册名称>/<镜像名称>:<标签>(标签默认为latest)
Dockerfile 指令总结
基于alpine制作tomcat镜像
1)构建基础alpine-base:3.15.0镜像,安装必要的工具
mkdir /data/dockerfile/{web/{nginx,apche,tomcat,jdk},system/{ubantu,centos,alpine}} -p
docker pull alpine
docker tag alpine alpine:3.15.0
#打上版本标签,不然久了自己也记不清版本了
cd /data/dockerfile/system/alpine
#创建alipine的仓库文件
cat > repositories <<EOF
http://mirrors.aliyun.com/alpine/v3.11/main
http://mirrors.aliyun.com/alpine/v3.11/community
#准备Dockerfile文件
cat > Dockerfile <<EOF
FROM alpine:3.15.0
LABEL maintainer="lijian"
COPY repositories /etc/apk
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && apk update && apk --no-cache add iotop gcc libgcc libc-dev libcurl libc-utils pcre-dev zlib-dev libnfs make pcre pcre2 zip unzip net-tools pstree wget libevent libevent-dev iproute2
RUN su - root -c "adduser -S -u 99 www"
RUN addgroup -S -g 2021 www && adduser -S -s /bin/bash -u 2021 www -g 2021
cat > build.sh << EOF
#!/bin/bash
docker build -t alpine-base:3.15.0 .
EOF
2)安装jdk
#准备Dockerfile文件
FROM alpine-base:3.15.0
LABEL maintainer="lijian"
RUN apk add --no-cache curl bash tree tzdata penjdk8-jre-base=8.275.01-r0 && rm -rf /var/cache/apk/* java -version
cat build.sh
#!/bin/bash
docker build -t tomcat-base:v8.5.50 .
3)构建tomcat基础镜像
#准备apache-tomcat-8.5.73.tar.gz移动至/data/dockerfile/web/tomcat
#准备Dockerfile文件
cat > /data/dockerfile/web/tomcat << EOF
FROM alpine-jdk:8.275.01r0
LABEL maintainer="lijian"
ENV LANG en_US.UTF-8
ENV TERM xterm
ENV TOMCAT_MAJOR_VERSION 8
ENV TOMCAT_MINOR_VERSION 8.5.73
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps
RUN mkdir /apps
ADD apache-tomcat-8.5.73.tar.gz /apps
RUN ln -s /apps/apache-tomcat-8.5.73 /apps/tomcat
#脚构建镜像
cat build.sh
#!/bin/bash
docker build -t tomcat-alpine:V8.5.73 .
测试试验:
4)构建业务镜像
#构建tomcat的主页文件
mkdir -p /data/dockerfile/web/tomcat/tomcat-app{1,2}
cd /data/dockerfile/web/tomcat/tomcat-app1
mkdir ROOT
echo Tish is gz > ROOT/index.jsp
tar zcf ROOT.tar.gz ROOT
#构建tomcat的配置文件,解压tomcat的压缩文件,修改server.xml
tar apache-tomcat-8.5.73.tar.gz
vim /data/dockerfile/web/tomcat/apache-tomcat-8.5.73/conf/server.xml
#构建tomcat业务镜像的启动脚本
cat > run_tomcat.sh << EOF
#!/bin/bash
echo "Tomcat Page in app11111" > /data/tomcat/webapps/ROOT/index.jsp
su - www -c "/apps/tomcat/bin/catalina.sh start"
su - www -c "tail -f /etc/hosts"
chmod a+x run_tomcat.sh
#构建tomcat的Dockerfile文件
cat > /data/dockerfile/web/tomcat/tomcat-app1/Dockerfile << EOF
FROM tomcat-alpine:V8.5.73
LABEL maintainer="lijian"
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD server.xml /apps/tomcat/conf/server.xml
ADD ROOT.tar.gz /data/tomcat/webapps
RUN chown -R www.www /apps/ /data/tomcat/
EXPOSE 8080
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
EOF
#构建tomcat业务构建脚本
cat > build.sh << EOF
#!/bin/bash
docker build -t tomcat-web:app1 .
EOF
#测试
root@ubundocker run -d -p 8080:8080 tomcat-web:app1
番外:删除名字是<none>的镜像
#查询所有镜像
#删除名字是<none>的镜像
docker images|grep "<none>"|tr -s " "|cut -d" " -f3|xargs docker rmi