镜像和容器
Docker中有几个重要的概念:
镜像(Image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。
容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器进程做隔离,对外不可见。
一切应用最终都是代码组成,都是硬盘中的一个个的字节形成的文件。只有运行时,才会加载到内存,形成进程。
而镜像,就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。
容器呢,就是将这些文件中编写的程序、函数加载到内存中允许,形成进程,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。
docker离线安装
下载docker-ce : https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz
wget https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz
1. mv docker/* /usr/bin/
2. vim /etc/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --selinux-enabled=false --graph=/home/docker/data
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
# docker 数据存储目录,与上面的--graph=/home/docker/data对应,默认路径在var下面,存储容量容易超标报错
mkdir -p /home/docker/data
3. chmod +x /etc/systemd/system/docker.service
4. systemctl daemon-reload
5. systemctl enable docker.service
6. systemctl start docker
出现的问题
- Docker容器启动时报错:container init caused “write /proc/self/attr/keycreate: permission denied““: unknown
- 编辑config文件:vi /etc/selinux/config
- 将SELINUX=enforcing改为SELINUX=disable
- 重启服务器
以上需要重启服务器,还有一种临时解决方案。 - setenforce 0
常用命令
docker xx --help命令查看docker的语法
docker pull nginx
docker images 查看拉取到的镜像
docker rmi nginx:latest
docker save -o [保存的目标文件名称] [镜像名称]
docker load -i nginx.tar
docker run:创建并运行一个容器,处于运行状态
docker pause:让一个运行的容器暂停
docker unpause:让一个容器从暂停状态恢复运行
docker stop:停止一个运行的容器
docker start:让一个停止的容器再次运行
docker rm:删除一个容器
docker run --name containerName -p 80:80 -d nginx
- docker run :创建并运行一个容器
- --name : 给容器起一个名字,比如叫做mn
- -p :将宿主机端口与容器端口映射,冒号左侧是宿主机端口,右侧是容器端口
- -d:后台运行容器
- nginx:镜像名称,例如nginx
docker exec -it mn bash
- docker exec :进入容器内部,执行一个命令
- -it : 给当前进入的容器创建一个标准输入、输出终端,允许我们与容器交互
- mn :要进入的容器的名称
- bash:进入容器后执行的命令,bash是一个linux终端交互命令
查看容器日志的命令:
- docker logs
- 添加 -f 参数可以持续查看日志
查看容器状态:
- docker ps
- docker ps -a 查看所有容器,包括已经停止的
数据卷
**数据卷(volume)**是一个虚拟目录,指向宿主机文件系统中的某个目录。一旦完成数据卷挂载,对容器的一切操作都会作用在数据卷对应的宿主机目录了。
这样,我们操作宿主机的/var/lib/docker/volumes/html目录,就等于操作容器内的/usr/share/nginx/html目录了
数据卷的作用:
- 将容器与数据分离,解耦合,方便操作容器内数据,保证数据安全
数据卷操作:
- docker volume create:创建数据卷
- docker volume ls:查看所有数据卷
- docker volume inspect:查看数据卷详细信息,包括关联的宿主机目录位置
- docker volume rm:删除指定数据卷
- docker volume prune:删除所有未使用的数据卷
挂载数据卷
docker run \
--name mn \
-v html:/root/html \
-p 8080:80
nginx \
这里的-v就是挂载数据卷的命令:
- `-v html:/root/htm` :把html数据卷挂载到容器内的/root/html这个目录中
docker run的命令中通过 -v 参数挂载文件或目录到容器中:
- -v volume名称:容器内目录
- -v 宿主机文件:容器内文
- -v 宿主机目录:容器内目录
数据卷挂载与目录直接挂载的区别:
- 数据卷挂载耦合度低,由docker来管理目录,但是目录较深,不好找
- 目录挂载耦合度高,需要我们自己管理目录,不过目录容易寻找查看
Dockerfile自定义镜像
# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录
ENV JAVA_DIR=/usr/local
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 暴露端口
EXPOSE 8090
# 入口,java项目的启动命令
ENTRYPOINT java -jar /tmp/app.jar
docker build -t javaweb:1.0 .
eg: 基于java:8-alpine镜像,将一个Java项目构建为镜像
实现思路如下:
- ① 新建一个空的目录,然后在目录中新建一个文件,命名为Dockerfile
- ② 拷贝课前资料提供的docker-demo.jar到这个目录中
- ③ 编写Dockerfile文件:
- a )基于java:8-alpine作为基础镜像
- b )将app.jar拷贝到镜像中
- c )暴露端口
- d )编写入口ENTRYPOINT
内容如下:
FROM java:8-alpine
COPY ./app.jar /tmp/app.jar
EXPOSE 8090
ENTRYPOINT java -jar /tmp/app.jar
docker-compose
安装docker-compose
建议从码云上下载,github容易上报错,地址docker-compose下载
下载下来后,将文件重命名为 docker-compose ,上传到 /usr/local/bin 目录,授权:
chmod +x /usr/local/bin/docker-compose
docker-compose -v
demo
eg: docker-compose.yml
version: "3.2"
services:
nacos:
image: nacos/nacos-server
environment:
MODE: standalone
ports:
- "8848:8848"
mysql:
image: mysql:5.7.25
environment:
MYSQL_ROOT_PASSWORD: 123
volumes:
- "$PWD/mysql/data:/var/lib/mysql"
- "$PWD/mysql/conf:/etc/mysql/conf.d/"
userservice:
build: ./user-service
orderservice:
build: ./order-service
gateway:
build: ./gateway
ports:
- "10010:10010"
可以看到,其中包含5个service服务:
nacos
:作为注册中心和配置中心image: nacos/nacos-server
: 基于nacos/nacos-server镜像构建environment
:环境变量MODE: standalone
:单点模式启动
ports
:端口映射,这里暴露了8848端口
mysql
:数据库image: mysql:5.7.25
:镜像版本是mysql:5.7.25environment
:环境变量MYSQL_ROOT_PASSWORD: 123
:设置数据库root账户的密码为123
volumes
:数据卷挂载,这里挂载了mysql的data、conf目录,其中有我提前准备好的数据
userservice
、orderservice
、gateway
:都是基于Dockerfile临时构建的
docker-compose常用命令
- docker-compose up
- docker-compose down
- docker-compose start
- docker-compose stop
- docker-compose --help
- docker-compose logs [id]
安装elasticsearch
1. cat /proc/sys/vm/max_map_count
2. (若值太小则执行此命令修改)sysctl -w vm.max_map_count=262144
3. 新建网桥
docker network create app
docker pull elasticsearch:7.4.2
4. 启动镜像
docker run -d \
--name elasticsearch \
--network app \
--restart=always \
-e "discovery.type=single-node" \
-p 9200:9200 -p 9300:9300 \
-v /home/docker/data/volume/esdata:/usr/share/elasticsearch/data \
-v /home/docker/data/volume/esplugins:/usr/share/elasticsearch/plugins \
elasticsearch:7.4.2
docker run --name elasticsearch -d -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 elasticsearch:7.4.2
下载IK分词器
- https://github.com/medcl/elasticsearch-analysis-ik/releases
- 解压到 /home/docker/volume/esplugins/ik 目录
- 重启es: docker restart elasticsearch
安装kibana
-
docker pull kibana:7.4.2
-
启动
docker run -d \
--name=kibana \
--network app \
--restart=always \
-p 5601:5601 \
-e ELASTICSEARCH_HOSTS=http://elasticsearch:9200 \
kibana:7.4.2
安装达梦7数据库
docker run -d \
--name dm7 \
--network app \
--restart=always \
-p 5236:5236 \
dm7:latest
Dockerfile:基于已安装好达梦的镜像 dm7:1
FROM dm7:1
WORKDIR /home/dmdbms/bin
#开放端口
EXPOSE 5236 22
# VOLUME /home/dmdbms/dameng
ENTRYPOINT ./dmserver path="/home/dmdbms/dameng/dm.ini"
运行dm8镜像
docker import dm8_docker.tar dm8:v01
docker run -itd -p 5236:5236 --network app --name dm8 dm8:v01 /bin/bash /startDm.sh