一、DOCKER基础
docker 码头工人(鲸鱼顶着集装箱)
开源的容器引擎;基于LCX容器技术,使用go语言开发;
采用cs架构,为容器创建轻量级、可移植的、自给自足的容器;
快速解决生产问题的一种技术;开发、运行和部署应用程序的开放管理平台;
开发人员利用docker可以开发和运行应用程序;
维护人员能利用docker部署和管理应用程序;
主要解决问题
保证程序运行环境的一致性;
降低配置开发环境,生产环境的复杂度和成本;
实现程序的快速部署和分发;
manages模块
data volumes:容器与宿主机之间,容器与容器之间共享存储方式,类似虚拟机与主机之间的共享文件目录;
image: 一个docker的可执行文件,其中包括运行应用程序所需的所有代码内容、依赖库、环境变量和配置文件等。
container:镜像被运行起来后的实例。
network:外部或者容器间如何互相访问的网络方式,如host模式、bridge模式;
二、docker命令
入门
systemctl 参数 docker (参数:start stop restart status)
sudo安装docker时,普通用户会出现权限bug,需要在执行的命令之前添加sudo;
或执行以下步骤一劳永逸解决sudo问题:
1、sudo groupadd docker
2、sudo gpasswd -a ${USER} docker
3、systemctl restart docker
4、newgrp - docker
镜像
镜像
是docker的可执行文件,包括运行应用程序所需的代码文件、依赖库、环境变量和配置文件等。通过镜像可创建一个或多个容器;
操作
搜索:docker search 镜像名称(eg。ubuntu、nginx等)
获取:docker pull 镜像名称 (镜像目录,默认 docker/image)
查看:docker images 或 docker image ls 或 docker images 镜像名称
重命名:docker tag 老镜像名称:老镜像版本 新镜像名称:新镜像版本 (PS:新老镜像同一个)
删除:docker rmi 镜像id/镜像名称:镜像版本
导出:docker save -o 打包名称.tar 镜像名称
导入:docker load < 镜像压缩文件名称
docker load --input 镜像压缩文件名称
容器
1、容器
轻量级、可移植、并将应用程序打包的技术,是应用程序可以在任何地方几乎相同的运行。具备生命周期。
2、操作
查看:docker ps
查看日志: docker logs -f 容器id
(docker log仅仅适用于以下驱动程序:local、json-file、journald)
查看docker日志驱动程序:docker inspect -f '{{.HostConfig.LogConfig.Type}}' 容器id
或 docker info | grep 'Logging Driver'
创建:docker create [option] --name 容器名称 依赖的镜像名称
docker create [option] image 命令
option: -t 为分配虚拟终端 -i 即使没有连接也要保持STDIN打开;
eg:docker create --it --name 容器名称 依赖的镜像名称 ls -a
启动:docker start 容器id或容器名称
-a 将当前shell的STDOUT或STDERR连接到容器上(标准输出或错误)
-i 将当前shell的STDIN连接到容器上;(标准输入)
执行:docker run 命令参数 镜像名称 执行命令
-d 在后台运行程序并打印出容器id
-rm 当容器退出运行后,自动删除
* run命令相当于create + start的集合
eg:启动一个镜像,输出内容并删除容器
docker run --rm --name 创建新容器的名称 依赖的镜像名称 /bin/echo "test";
进入:
docker run --name 容器名称 -it 镜像名称 /bin/bash
或 docker run -it --name 容器名称 镜像名称 /bin/bash
退出:exit 或 ctrl + D
暂停:暂停一个或多个运行状态的容器
docker puase 容器id或容器名称
取消暂停:取消一个或多个暂停状态的容器,恢复运行
docker unpuase 容器id或容器名称
重启:docker restart [-t 延迟时间] 容器id或容器名称
停止:docker stop 容器id或容器名称
删除:docker rm/ kill 容器id或容器名称
*生产方式进入容器脚本
创建docker_in.sh脚本,脚本内容:
#!/bin/bash
#定义进入仓库函数
docker_in(){
NAME_ID=$1
PID=$(docker inspect --format {{.state.pid}}$NAME_ID)
nsenter --target $PID --mount --uts --ipc --net --pid
}
执行:docker_in $1($1容器id)
赋值权限:
chmod +x docker_in.sh
3、容器与虚拟机区别,容器与镜像的区别
容器与虚拟机相同点:
共享使用物理资源;
生命周期(创建、运行、暂停、关闭等);
可以安装各种应用,例如redis、mysql等;
创建后会存储在宿主机上,容器的存储路径linux:var/lib/docker/containers ;
容器不等于虚拟机
//TODO
容器依赖镜像
镜像是只读层。
数据管理
针对数据持久化保存,容器之间数据共享的解决方案:数据卷 & 数据卷容器。
1、数据卷 data volumes
将宿主机的某个目录,映射到容器中,作为数据存储的目录,就可以在宿主机对数据进行存储。
数据卷 data volumes:容器内数据直接映射到本地主机环境。
数据卷与目录
启动一个容器挂载数据卷: docker run -itd --name [容器名称] -v [宿主机目录]:[容器目录][镜像名称] [命令(可选)]
创建测试文件(宿主机目录下/home/itcast/tmp/):echo “file” >/tmp/file.text
挂载数据卷(目录):docker run itd --name test1 -v /home/itcast/tmp/:/test1/ nginx
测试效果:进入容器 docker exec -it 容器id /bin/bash
查看测试文件:cat /test1/file.text
docker挂载数据卷默认权限为rm,用户可以通过ro设置为读写。
挂载文件到容器,使用文件工具编辑文件后,可能会造成文件改变。从docker1.1.0开始会报错。推荐挂载目录。
数据卷特性
1、可以在容器间共享和重用,本地与容器间传递数据更高效;
2、对数据卷的修改会立马有效,容器内部与本地目录均可;
3、对数据卷的更新,不会影响镜像,对数据与应用进行了解耦操作;
4、卷会一直存在,直到没有容器使用;
2、数据卷容器 data volumes containers
多个容器之间共享持续更新的数据。目的是用来提供数据卷 以供其他容器使用。
数据卷容器:使用特定容器维护数据卷。
数据卷容器操作流程
- 创建数据卷容器 (docker create -v [容器数据卷目录] --name [容器name] [镜像名称] [命令(可选)])
- 挂载数据卷 (docker run --volumes -from [数据卷容器id/name])-tid --name [容器名字] [镜像名称] [命令(可选)])
PS:docker服务配置实例脚本
运行eg:shoppingmall-front.sh restart
shoppingmall-front.sh
DOCKER_NAME="shoppingmall-front"
IMAGE_NAME="shoppingmall-front"
IMAGE_VERSION="latest"
IMAGE_TAG="$IMAGE_NAME:$IMAGE_VERSION"
MACHINE_PORT=9006
CONTAINER_PORT=8080
EXT_OPT=" "
# port
EXT_OPT="$EXT_OPT -p $MACHINE_PORT:$CONTAINER_PORT "
# enviroment
EXT_OPT="$EXT_OPT -e TZ=Asia/Shanghai"
# volume
EXT_OPT="$EXT_OPT -v /home/shopuser/web_upload:/home/shopuser/web_upload "
EXT_OPT="$EXT_OPT -v /etc/localtime:/etc/localtime "
execScript="docker run -d --restart=always --name $DOCKER_NAME $EXT_OPT $IMAGE_TAG"
. ./dockerscript.sh
dockerscript.sh
seed_running() {
seedcount=$(docker ps -f 'status=running' -f name=$DOCKER_NAME | wc -l)
if [[ $seedcount -eq 2 ]]; then
return 0
else
return 1
fi
}
start() {
echo $GREEN"Start $DOCKER_NAME Container..."
seed_exists
if [[ $? == 0 ]]; then
docker start $DOCKER_NAME
docker logs -f $DOCKER_NAME
else
runResult=`${execScript}`;
echo "$runResult";
runResultLength=`expr length $runResult`;
echo "$runResultLength";
if [ "$runResultLength" -eq 64 ]; then
#docker logs -f $DOCKER_NAME
echo "${DOCKER_NAME} container run success";
else
echo "run ${DOCKER_NAME} container fail";
fi
fi
}
restart() {
echo "restart $DOCKER_NAME Container..."
docker stop $DOCKER_NAME
start
}
stop() {
echo $RED"Stopping $DOCKER_NAME Container..."
docker stop $DOCKER_NAME
echo $RED"Removing $DOCKER_NAME Container..."
docker rm $DOCKER_NAME
docker ps -a
}
enter() {
# docker exec -it $DOCKER_NAME bash
docker exec -it $DOCKER_NAME sh
}
logs() {
echo $BLUE"View ${DOCKER_NAME} Container logs";
docker logs -f --tail 100 $DOCKER_NAME
}
status() {
# status=`docker inspect ${DOCKER_NAME} -f '{{.State.Status}}'`
seed_exists
if [[ $? == 0 ]]; then
echo "${DOCKER_NAME} Container exists?: "$GREEN"YES"$RESET
else
echo "${DOCKER_NAME} Container exists?: "$RED"NO (!)"$RESET
echo "${DOCKER_NAME} Container doesn't exist, thus it is NOT running. Run $0 start"$RESET
return
fi
seed_running
if [[ $? == 0 ]]; then
echo "${DOCKER_NAME} Container running?: "$GREEN"YES"$RESET
else
echo "${DOCKER_NAME} Container running?: "$RED"NO (!)"$RESET
echo "${DOCKER_NAME} Container isn't running. Start it with $0 run"$RESET
return
fi
}
help(){
echo "Usage: $0 COMMAND [DATA]"
echo
echo "Commands: "
echo " install: pulls latest docker image from server."
echo " build: only builds muse container (from docker file)"
echo " start: start an existing server instance."
echo " status: show status of the server container"
echo " stop: stop the server instance in the current directory on the local machine."
echo " restart: restart the server instance in the current directory on the local machine."
echo " logs: take a look at the most recent logs from the docker container."
echo " enter: enter a bash session in the container"
echo
exit
}
if [ "$#" -ne 1 ]; then
help
fi
case $1 in
build)
echo "You may want to use '$0 install' for a binary image instead, it's faster."
build
;;
install)
install
;;
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 5
start
;;
status)
status
;;
enter)
enter
;;
logs)
logs
;;
*)
echo "Invalid cmd"
help
;;
esac
2020.09-2020.10
源于为节约服务器成本,合并多个服务到一台服务上。此时,使用docker容器部署服务。