基础概念、安装与卸载、命令、部署、可视化portainer、自制镜像、容器的卷技术、DockerFile、Docker网络、Springboot镜像、Compose
基础概念
1
虚拟技术和容器技术对比
虚拟技术 | 容器技术 | |
---|---|---|
原理 | 虚拟出硬件,运行一个完整的操作系统 | 容器应用直接运行在宿主机,无内核,相互隔离 |
资源占用 | 多 | 少 |
启动 | 慢 | 快 |
2
容器技术优点
1)应用更快交付和部署
2)更便捷的升级
3)更简单的系统运维
4)更高效的计算机资源利用
3
镜像、容器、仓库
1)镜像
相当于一个应用模板,可通过模板来创建容器服务
2)容器
独立运行的一个或一组应用,通过镜像创建
3)仓库
存放镜像的地方,分为私有仓库和公有仓库
安装与卸载
1
安装
1)卸载老版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2)设置远程库
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3)安装docer
$ sudo yum install docker-ce docker-ce-cli containerd.io
如果报以下错误
package docker-ce-3:19.03.8-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed
需更改镜像,如下
$ yum install -y https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm
再执行
yum install docker-ce docker-ce-cli containerd.io
4)启动
$ sudo systemctl start docker
5)设置自启动
$ sudo systemctl enable docker
6)测试
$ docker run hello-world
执行后docker会先在本地仓库查找有无镜像,如果没有再去远程仓库查找并下载下来运行。如果远程仓库没有,会报错
7)阿里云镜像加速
$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://0djjuh99.mirror.aliyuncs.com"]
}
EOF
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
2
卸载
1)卸载主程序
$ sudo yum remove docker-ce docker-ce-cli containerd.io
2)删除残留
$ sudo rm -rf /var/lib/docker
3
原理
1)Docker如何工作?
Docker是一个client-server结构的系统,Docker的守护进程运行在主机上,DockerServer接收到DockerClent的Socket指令后,就会执行这个指令
2)Docker为什么比虚拟机快?
(1)Docker有着比虚拟机更少的抽象层
(2)Docker利用的是宿主机内核,虚拟机用的是GuestOs
3)Docker镜像加载原理
Docker镜像由一层一层的文件系统组成,这种层级文件系统称为UnionFs
4
离线安装
1)将docker包复制到机器上
2)解压并复制
tar xvf docker-17.03.0-ce.tgz
cp docker/* /usr/bin/
3)执行
vi /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
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
4)授权
chmod +x /etc/systemd/system/docker.service
systemctl daemon-reload
5)设置开启启动
systemctl enable docker.service
6)启动
systemctl start docker
6)安装docker-compose
mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose -v
命令
1
Docker常用命令
命令 | 含义 |
---|---|
docker version | 显示docker的版本信息 |
docker info | 显示docker的系统信息,包含镜像和容器的数量 |
docker 命令 --help | 帮助命令 |
2
镜像命令
1)查看所有镜像
$ docker images
执行后会显示一张表,以下是表的字段解释
字段 | 含义 |
---|---|
REPOSITORY | 仓库源 |
TAG | 标签 |
IMAGE ID | 镜像ID |
CREATED | 创建时间 |
SIZE | 镜像大小 |
2)搜素镜像
$ docker search 镜像名
3)下载镜像
$ docker pull 镜像名
4)删除指定镜像
$ docker rmi -f 镜像id
3
容器命令
1)创建容器
$ docker run 可选参数 imagename
可选参数
参数 | 含义 |
---|---|
--name="name" | 容器名 |
-d | 后台方式运行 |
-it | 交互方式运行 |
-p | 指定容器端口 |
$ docker run -itd ubuntu /bin/bash
运行ubuntu镜像
后台创建容器
$ docker run -d centos
容器创建后会停止服务,且无法唤醒
2)退出容器
$ exit
退出但不停止容器ctrl+p+q
3)启动和停止容器
(1)启动容器
$ docker start 容器id
(2)重启容器
$ docker restart 容器id
(3)停止容器
$ docker stop 容器id
(4)强制停止容器
$ docker kill 容器id
(5)设置容器启动后自动运行
$ sudo docker update 容器名 --restart=always
4)查看容器
(1)查看所有容器
$ docker ps -a
(2)查看运行中的容器
$ docker ps
5)删除容器
$ docker rm -f 容器id
清除所有处于停止状态的容器
$ docker container prune
4
其他命令
1)查看日志
编写一段shell脚本
$ docker run -d ubuntu /bin/sh -c"while true;do echo zhanghuan;sleep 1;done"
查看日志
$ docker logs -tf --tail 10 容器id
会不断打印日志
2)查看容器进程信息
$ docker top 容器id
3)查看镜像源数据
$ docker inspect 镜像id
4)进入容器
(1)进入后新开启一个终端
$ docker exec -it 容器id
(2)进入正在执行的终端
$ docker attach 容器id
5)容器内拷贝文件
$ docker cp 容器id:目录 本机目录
6)查看cpu状态
$ docker stats
7)从数据库dump
docker exec -it $CONTAINER_NAME mysqldump -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -t --skip-add-locks --skip-comments --skip-extended-insert --skip-triggers $DB_BIZ_NAME $table >${FILE_PATH_INITDATA}/${DB_BIZ_NAME}.$table.sql
8)docker查看日志
docker logs [OPTIONS] CONTAINER
Options:
--details 显示更多的信息
-f, --follow 跟踪实时日志
--since string 显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
--tail string 从日志末尾显示多少行日志, 默认是all
-t, --timestamps 显示时间戳
--until string 显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)
9)docker导出镜像
docker save nginx:latest -o nginx.tar nginx:latest
# docker save tag名 -o 目标文件 镜像
10)加载镜像
docker load -i nginx.tar
11)修改镜像的tag
docker tag 4c51 rocketmq:4.7
部署
1
nginx
1)下载镜像
$ docker pull niginx
2)创建容器
$ docker run -d -p3344:80 nginx
-p后的第一个端口是宿主机端口,第二个端口是容器端口
3)外部访问测试
$ curl localhost:334
2
tomcat
1)下载镜像
$ docker pull tomcat
2)创建容器
$ docker run -d -p81:8080 tomcat
3)拷贝文件
tomcat被阉割了,需要进入容器从/usr/local/tomcat/webapps.dist中拷贝所有文件至/usr/local/tomcat/webapps.
$ docker exec -it 容器id /bin/bash
$ cp -r webapps.dist/* webapps
可视化portainer
Docker 图形界面管理工具,提供一个后台面板供操作,超好用
$ docker run -d -p 8088:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
自制镜像
1)将容器配置好
2)执行命令
$ docker commit -a="作者" -m"信息" 镜像id 镜像名:版本号
容器的卷技术
1
用处
1)容器持久化和同步操作
2)在容器外部配置容器内部环境
3)容器间共享数据
2
命令
$ docker run -it -v /test:/test centos /bin/bash
将宿主机的/test目录与容器的/test目录进行绑定
3
创建mysql同步数据容器
$ docker run -p 3389:3306 --name mysql\
-v /mydata/mysql/log:/var/log/mysql\
-v /mydata/mysql/data:/var/lib/mysql\
-v /mydata/mysql/conf:/etc/mysql\
-e MYSQL_ROOT_PASSWORD=root\
-d mysql:5.7
4
具名挂载、匿名挂载
(1)具名挂载
$ docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx nginx
不指定外部路径,指定一个挂载名。通过以下命令查看挂载位置
$ docker volue inspect juming-ngin
默认放置在 /var/lib/docker/volumes/下
(2)匿名挂载
$ docker run -d -p 8080:80 --name nginx02 -v :/etc/nginx nginx
不指定外部路径,也不指定挂载名,会自动生成一个随机长名
(3)读写权限
$ docker run -d -p --name nginx02 -v :/etc/nginx:ro nginx
$ docker run -d -p --name nginx02 -v :/etc/nginx:rw nginx
ro表示容器只读,rw容器可读写
5
Dockerfile
通过读取文件中配置信息后自动构建镜像
创建一个名为dockerfile(任意命名)构建文件
FROM centos
VOLUME ["volume01","volume02"]#volume01和volume02是容器内目录
CMD echo "---end---"
CMD /bin/bash
执行命令
$ docker build -f 文件名 -t 镜像名:版本号 .
执行后将创建一个镜像
6
容器共享挂载卷
例如我门之前创建了一个名为centos01的容器,现在再创建一个名为centos02的容器共享centos01的挂载卷
$ docker run -it --name centos01 --volumes-from centos02 centos
DockerFile
1
dockerfile指令
指令 | 解释 |
---|---|
FROM | 基础信息 |
MAINTAINER | 维护者信息 |
RUN | 构建时运行的命令 |
ADD | 要添加的内容 |
WORKDIR | 工作目录 |
VOLUME | 挂载目录 |
EXPOSE | 保留端口配置 |
CMD | 指定容器启动时需要运行的命令 |
ENTRYPOINT | 指定容器启动时需要运行的命令,可进行追加 |
ONBUILD | 运行onbuild后触发指令 |
COPY | 类似add,将文件拷贝到镜像中 |
ENV | 构建时设置环境变量 |
2
构建centos
1)创建构建文件myfile
FROM centos
MAINTAINER zhanghuan
ENV MYPATH /usr.local
WORKDIR $MYPTH
RUN yum -y install vim
RUN yum -y install net-tolls
EXPOSE 80
CMD echo $MYPATH
CMD echo "___end___"
CMD /bin/bash
2)执行构建命令
$ docker build -f myfile -t mycentos:1.0 .
Docker网络
1
默认网络
容器创建后,会和宿主机器自动建立连接(Veth-Pair),容器间、容器与宿主机之间可以通过分配的默认ip地址ping通
2
通过容器名访问容器
$ docker run -d -P --name tomcat3 --link tomcat2 tomcat
此时tomcat3可通过容器名访问tomcat2
$ docker exec -it tomcat3 ping tomcat2
能ping通,但反向不能。
--link本质上就是再默认网络上增加了一个hosts映射
3
网路的4种模式
1)host模式
相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
2)container模式
指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信
3)None模式
该模式将容器放置在它自己的网络栈中,但是并不进行任何配置。实际上,该模式关闭了容器的网络功能,在以下两种情况下是有用的:容器并不需要网络
4)bridge模式
相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上
4
自定义网络
创建网络
1)创建一个名为mynet的网络
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
2)将容器连入自定义网络的两种方式
(1)创建容器方式连入网络
$ docker run -d -P --net mynet tomcat
(2)将已启动的容器连入网络
$ docker network connect mynet tomcat1
注意
连入自定义网络的容器可通过容器名访问
其他命令
(1)查看所有网络
$ docker network ls
(2)查看网络配置
$ docker network inspect mynet
(3)相关
# 列出运行在本地 docker 主机上的全部网络
docker network ls
# 提供 Docker 网络的详细配置信息
docker network inspect <NETWORK_NAME>
# 创建新的单机桥接网络,名为 localnet,其中 -d 不指定的话,默认是 bridge 驱动。并且主机内核中也会创建一个新的网桥。
docker network create -d bridge localnet
# 删除 Docker 主机上指定的网络
docker network rm
# 删除主机上全部未使用的网络
docker network prune
# 运行一个新的容器,并且让这个容器加入 Docker 的 localnet 这个网络中
docker container run -d --name demo1 --network localnet alpine sleep 3600
# 运行一个新的容器,并且让这个容器暴露 22、20 两个端口
docker container run -d --name web --expose 22 --expose 20 nginx
# 运行一个新的容器,并且将这个容器的 80 端口映射到主机的 5000 端口
docker container run -d --name web --network localnet -p 5000:80 nginx
# 查看系统中的网桥
brctl show
5
docker容器内部不可访问宿主机的ip
docker run -d -p8848:8848 --network=bridge 354
启动时加上 --network=host,可解决。在docker-compose中,
version: '3.0'
services:
nacos:
container_name: nacos
image: nacos:1.1
volumes:
- "/root/nacos/conf:/nacos/conf"
- "/root/nacos/logs:/nacos/logs"
network_mode: host
ports:
- "8848:8848"
在容器里可访问外部局域网络,但在外部不可访问到该容器
–network=bridge,在容器里不可访问外部局域网络,但在外部可访问到该容器
6
使用外部已存在网络
1)创建网络
docker network create -d bridge my-net
2)docker-compose中引用
version: "2.1"
services:
nginx-php:
image: nginx
ports:
- "82:80"
volumes:
- ./www:/usr/share/nginx/html
- ./conf:/etc/nginx
- ./logs:/var/log/nginx
networks:
- lnmp-network
- my-net #加入网络
php:
image: 6bfd101
volumes:
- ./www:/www
networks:
- lnmp-network
networks:
lnmp-network:
my-net: #指向外部已存在的docker网络
external: true #是否是外部网络,填true
Springboot镜像
1
打包前配置文件
如果连接的是本机内另一个容器的数据库,需要在本机内创建网络,将数据库所在容器接入,然后再将配置文件里数据库的配置进行如下修改
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql:3306/subject?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
server:
address: 0.0.0.0
"mysql:3306/subject?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8"里mysql是指mysql所在容器的容器名
2
制作镜像
将jar包上传到服务器,再新建一个名为Dockerfile的文件,内容如下
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8081"]
EXPOSE 8081
ENTRYPOINT ["java","-jar","app.jar"]
执行以下命令制作镜像
$ docker build -t subject-service:1.0 . #打包成的镜像名,后面的.不要忘记
执行完成后,将生成一个RESPONSITORY名为subject-service,tag为1.0的镜像
3
运行
$ docker run -d -p 8081:8081 --net mynet subject-service:1.0
Compose
1
安装
1)下载
$ curl -L https://get.daocloud.io/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
2)设置可运行
$ chmod +x /usr/local/bin/docker-compose
3)查看版本
$ docker-compose --version
2
卸载
$ sudo rm /usr/local/bin/docker-compose
2
使用步骤
1)创建目录
2)将运行的web应用复制到目录下,这里是app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == '__main__':
app.run()
3)创建web应用的Dockerfile
FROM python:3.7-alpine
Add . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
以及用到的requirements.txt
flask
redis
4)创建docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
5)运行命令
$ docker-compose up
6)停止服务
$ docker-compose down
3
快速创建博客
1)配置docker-compose.yml
version: '2'
services:
db:
image: mysql:5.7
volumes:
- "./data/db:/var/lib/mysql"
ports:
- "8080:3306"
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
links:
- db
ports:
- "8888:80"
restart: always
2)运行命令
$ docker-compose up
从docker数据库导出数据的案例
#!/bin/bash
BASE_HOME=`pwd`
EXPORT_FILE_PATH=$BASE_HOME/mysql/olddata
FILE_PATH_INITDATA=${EXPORT_FILE_PATH}/initdata
FILE_PATH_TMP=${EXPORT_FILE_PATH}/tmp
# 数据库账号密码信息
MYSQL_USER="root"
MYSQL_PASSWORD="Aa12345678"
MYSQL_PORT=28593
MYSQL_HOST=10.0.1.170
DB_BIZ_NAME="kiam"
# 获取docker容器
CONTAINER_NAME=mysql-$(whoami)-$MYSQL_PORT
# 将要导出的表放到一个数组中
TABLE_ARRAY=(
tb_org
tb_app
tb_user
tb_user_job
tb_mgr_admin
tb_role
tb_mgr_role_link
tb_mgr_admin_area_link
tb_mgr_admin_role_link
tb_user_role_link
tb_role_resource_link
tb_app_org_idlist
tb_app_user_idlist
tb_app_res_field_link
tb_app_res_info
tb_app_res_sync_link
tb_app_res_sync_policy
tb_app_res_sync_policy_ext
tb_app_transrule_link
tb_transrule
tb_res_dispatch_history
tb_res_event_action_trace
tb_res_event_detail
)
function exportInitData () {
if [ ! -e ${FILE_PATH_INITDATA} ];then
mkdir -p ${FILE_PATH_INITDATA}
fi
# 将表格内容中数据导出成sql文件到指定的文件夹
for table in ${TABLE_ARRAY[*]}
do
docker exec -it $CONTAINER_NAME mysqldump -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASSWORD -P$MYSQL_PORT -t --skip-add-locks --skip-comments --skip-extended-insert --skip-triggers $DB_BIZ_NAME $table >${FILE_PATH_INITDATA}/${DB_BIZ_NAME}.$table.sql
echo "导出$table"
done
for file in ${FILE_PATH_INITDATA}/*;
do
deleteRow $file
done
# 将所有的sql文件合并成一个sql文件
cat ${FILE_PATH_INITDATA}/*.sql > ${EXPORT_FILE_PATH}/kiam_initdata.sql
echo "合并"
}
function deleteRow() {
#删除首行
sed -i '1d' $1
}
exportInitData
echo "导出初始化数据完成!!"
cd ${BASE_HOME}
exit 0
标签:容器,run,--,30,2020,镜像,Docker,tb,docker
From: https://www.cnblogs.com/sylvesterzhang/p/18089861