docker 从入门到实践 离线版本
docker pull dockerpracticecn/docker_practice
docker run -it --rm -p 4000:80 dockerpracticecn/docker_practice
Yum在线安装
1 . 卸载旧版
sudo yum remove docker-ce \
docker-ce-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
第二步:安装一组工具
sudo yum install -y yum-utils
第三步:设置 yum 仓库地址
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docke
r-ce/linux/centos/docker-ce.repo
第四步:更新 yum 缓存
sudo yum makecache fast #yum 是包管理器
第五步:安装新版 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
3 Docker入门实践**
第一步:启动docker
sudo systemctl start docker
第二步:设置 docker 开机启动
`sudo systemctl enable docker
第三步:镜像加速
由于国内网络问题,需要配置加速器来加速。修改配置文件 /etc/docker/daemon.json
下面命令直接生成文件 daemon.json
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-level": "warn",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"data-root": "/var/lib/docker"
}
EOF
说明:在执行如上指令时,保证你的登录用户为root管理员用户。
第四步:重新启动服务。
重新加载docker配置
sudo systemctl daemon-reload
#重启docker服务
sudo systemctl restart docker
第五步:查看镜像配置
docker info
第六步:运行 hello-world 镜像,验证 docker
sudo docker run hello-world
七步:检查docker 镜像
docker images
第八步:检查已启动的docker 服务 (正在运行的)
docker ps
假如希望查看所有镜像,包含没有运行的镜像容器,可以执行如下指令:
docker ps –all
第九步:停止docker服务
docker stop
服务id
第十步:删除docker 镜像
docker image rm hello-world
假如镜像被占用着是不可以直接被删除的,需要先删除应用此镜像的容器,例如
docker container rm 容器名或容器id
1.6Docker数据管理实践
在容器中管理数据主要有两种方式:
挂载主机目录 (Bind mounts)-最常用 (docker run –v 宿主机目录:容器目录)
数据卷(Volumes)
创建数据卷
dockervolume createcontainer-vole
查看所有的数据卷
docker volume ls
查看指定 数据卷 的信息
docker volume inspect container-vol
查询的结果:
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/container-vol/_data",
"Name": "container-vol",
"Options": {},
"Scope": "local"
}
]
第三步:启动挂载数据卷的容器
docker run -it --mount source=container-vol,target=/root centos:7 bash
docker run -it -v container-vol:/root centos:7 bash
第四步:删除数据卷(如果数据卷被容器使用则无法删除)
docker volume rm container-vol
1.6.4挂载主机目录(常用)
docker run -it -v /usr/app:/opt/app centos:7 bash
1)/usr/app:为宿主机目录
2)/opt/app: 为启动容器的一个目录
查看挂载目录信息
docker inspect 91a #91a 为容器id
查看挂载目录信息
"Mounts": [
{
"Type": "bind",
"Source": "/usr/app",
"Destination": "/opt/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
Dockerfile文件
编写 文件名称
第一步:编写FROM语句(关键字一定要大写,例如FROM不能写小写)
1.
touch Dockerfile
FROM centos:7
ADD jdk-8u51-linux-x64.tar.gz /usr/local/docker
ENV JAVA_HOME=/usr/local/docker/jdk1.8.0_51 \
PATH=/usr/local/docker/jdk1.8.0_51/bin:$PATH
CMD [‘bash’]
使用 Dockerfile 构建镜像(在Dockerfile所在目录执行docker指令)
docker build -t jdk:8 .
#不要丢掉这里的点
1.7.4运行镜像文件
docker run –it jdk:8 bash
进入容器以后,可以通过echo $PATH查看环境变量,并可以通过java –version查看JDK版本信息。
1.7.5镜像导出导入操作
镜像导出(linux系统中的镜像文件下载到本地-例如window)
docker save jdk:8 | gzip > jdk8.tar.gz
镜像导入(要再jdk8.tar.gz文件所在目录下执行)
docker load < jdk8.tar.gz
mysql 数据库 镜像的练习
##在hub.docker.com上搜索mysql镜像
sudo docker pull mysql:8.0.23
第三步:检查mysql镜像
sudo docker images
第四步:启动运行mysql镜像 (docker run 用于启动一个容器)
换行符 -v 绑定文件夹命令 -d 后台运行 -e 输入密码
sudo docker run -p 3306:3306 --name mysql \
-v /usr/local/docker/mysql/mysql-files:/var/lib/mysql-files \
-v /usr/local/docker/mysql/conf:/etc/mysql \
-v /usr/local/docker/mysql/logs:/var/log/mysql \
-v /usr/local/docker/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:8.0.23
停止mysql服务(可选)
docker stop mysql
第六步:启动mysql服务
docker start mysql
第七步:查看docker启动的服务
docker ps
第八步:进入容器 (退出容器用exit)
sudo docker exec -it mysql bash
第九步:登陆(默认密码root),一定要先进入mysql容器。
mysql -uroot -proot
第十步:设置mysql开机自启动(可选)
docker update mysql --restart=always
FAQ分析
如何重启mysql服务?
docker restart mysql
(2)使用 window连接这个数据库
创建数据库用户
```cpp
create user ‘tony’@’%’ identified by ‘tony’;
第二步:重启docker
```cpp
```cpp
grant all on *.* to ‘tony’@‘%’
第三步:启动mysql
```cpp
docker start mysql
关闭防火墙设置:
关闭linux宿主机的防火墙
sudo systemctl stop firewalld.service
sudo systemctl stop firewalld.service
第二步:在window平台通过新创建用户连接mysql,例如,在命令行执行如下指令:
mysql -utony –h 192.168.174.130 -p #-h后面 虚拟机的ip地址
出现Plugin caching_sha2_password could not be load错误(出现这个错误往往与数据库的版本有关系),可以先登录docker环境下mysql的root用户(出现此情况 原因 1.本地数据库 与 远程数据版本不一致 ,需要升级 本地数据库驱动)
ALTER USER 'tony'@'%' IDENTIFIED BY 'tony' PASSWORD EXPIRE NEVER;
ALTER USER 'tony'@'%' IDENTIFIED WITH mysql_native_password BY 'tony';
FLUSH PRIVILEGES;
练习 2.。安装Redis数据库
1.拉去 镜像参数
docker pull redis
创建redis配置文件目录
mkdir -p /usr/local/docker/redis/conf
在配置文件录下创建redis.conf配置文件(因为redis镜像中这个redis.conf是一个目录所以要先创建一个这个配置文件,否在我们本地挂载点也会变成一个目录)
touch /usr/local/docker/redis/conf/redis.conf
#### -p 端口号 --name 名字 为 redis --v绑定路径 -d后台运行
sudo docker run -p 6379:6379 --name redis \
-v /usr/local/docker/redis/data:/data \
-v /usr/local/docker/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
第三步:查看正在运行的进程
docker ps
第四步:控制台直接连接redis测试
docker exec -it redis bash
第五步:检测redis 版本
Redis-server –v # 或者 redis-cli -v
如何停止redis服务?
docker stop redis
如何启动redis服务?
docker start redis
如何重启 redis 服务?
docker restart redis
如何查看 redis 服务版本?
docker exec -it redis redis-server -v
如何关闭防火墙?
systemctl stop firewalld
安装Ngnix代理练习
第一步:拉取ngnix镜像 (从这里hub.docker.com去查找)
docker pull nginx:latest
(lastst 可以省略)
第二步:查看images镜像
docker images
第三步:简单启动
docker run --name nginx -d nginx
检测安装的内容docker exec nginx ls -l /etc/nginx
第四步:拷贝安装好的配置文件
docker cp -a nginx:/etc/nginx /usr/local/docker/nginx
第五步:强制卸载刚刚安装的nginx
docker rm -f nginx
第六步:启动nginx容器,运行nginx镜像
sudo docker run -p 80:80 --restart always --name nginx \
-v /usr/local/docker/nginx/:/etc/nginx/ \
-v /usr/local/docker/nginx/conf.d:/etc/nginx/conf.d \
-d nginx
负载均衡练习
1.创建 三个 jar 包 端口 分别 为 89018902,8903; main代码如下
@RestController
public class HelloController {
@Value("${server.port}")
private String port;
//要求动态获取真实服务器端口号
@RequestMapping("/hello")
public String doSayHello() {
return "server:"+port+" say hello ";
}
}
第二步:将这个jar包扔到linux宿主机上一份,假设地址为/home/servers
第三步:基于jdk:8镜像文件,运行jar文件
#/home/servers 为 jar 包位置 usr/sca为 docker 路径位置(没有可以自动生成)
docker run -d -p 8091:8091 --name tomcat8901 -v /home/servers:usr/sca
jdk:8 java –jar /usr/sca/tomcat8901.jar
第四步:配置请求转发。
配置nginx实现请求的转换,在宿主机环境下可编辑 /usr/local/default/nginx/conf.d/目录中的default.conf文件,详细配置请求转发proxy_pass http://192.168.174.130:8901;
代码如下:
**server {
listen 80;
listen [::]:80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://192.168.174.130:8901;
#root /usr/share/nginx/html;
#index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# **pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000**
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}**
第三步:配置完以后重新启动nginx。
docker restart nginx
第四步:对资源进行访问检测请求转发实现。
http://192.168.174.130:80/hello
均衡负载
业务说明
需要搭建tomcat服务器集群,共同抗击高并发.这时需要使用反向代理服务器.同时配置负载均衡.
说明:准备3台tomcat服务器.端口号分别为8901/8902/8903.
**启动集群**
#端口8901 已经启动
docker run -d -p 8901:8901 --name tomcat8901 -v /root/servers:/usr/sca
jdk:8 java –jar /usr/sca/tomcat8901.jar
docker run -d -p 8901:8901 --name tomcat8901 -v /root/servers:/usr/sca
jdk:8 java –jar /usr/sca/tomcat8901.jar
docker run -d -p 8903:8903 --name tomcat8903 -v /root/servers:/usr/sca
jdk:8 java –jar /usr/sca/tomcat8902.jar
轮询策略
说明:根据配置文件的顺序,依次访问服务器.
#配置web服务集群 默认是轮询策略,打开conf.d目录下default.conf文件,进行负载均衡配置,代码参考如下:
修改: /usr/local/default/nginx/conf.d/目录中的default.conf文件 修改文件前注意备份
修改
upstream gateways{
server 192.168.174.130:8901;
server 192.168.174.130:8902;
server 192.168.174.130:8903;
}
#配置后台管理服务器
server {
listen 80;
server_name localhost;
location / {
#实现http请求的转发
proxy_pass http://gateways;
}
}
权重策略
#配置windows集群 默认是轮循策略 权重
upstream gateways{
server 192.168.174.130:8901 weight=1;
server 192.168.174.130:8902 weight=2;
server 192.168.174.130:8903 weight=6;
}
IPHashce 策略
问题说明:如果采用集群的部署,如果做敏感操作时,要求用户必须登录.但是由于nginx实现了负载均衡的操作,导致用户的Session数据不同共享.从而导致用户频繁登录.用户体验较差.
问题: nginx实现了tomcat负载均衡. 导致用户每次访问都是不同的服务器.
解决方案: 能否让用户每次访问同一台服务器 IPHASH策略
IPHASH调用原理 如图所示:
配置如下:
#配置windows集群 默认是轮询策略 权重
upstream geteways {
ip_hash;
server 192.168.227.131:10001 weight=6;
server 192.168.227.131:10002 weight=3;
server 192.168.227.131:10003 weight=1;
}
ps 设置 iphash 后 weight 不起作用
IPHASH存在的问题
- IPHASH如果一旦服务器出现异常,导致业务失效.
- 可能会出现负载不均的现象.负载有高有低(可在测试中试用).
一般不会使用IPHASH,一般在测试中使用.
NGINX常用属性:
upstream geteways {
#ip_hash;
server 192.168.227.131:8901 down;
server 192.168.227.131:8902;
server 192.168.227.131:8903;
}
BACKUP 设计
说明:备用机设置,正常情况下该服务器不会被访问.当主机全部宕机或者主机遇忙时,该服务器才会访问.
upstream geteways {
#ip_hash;
server 192.168.227.131:8901 down;
server 192.168.227.131:8082;
server 192.168.227.131:8903 backup;
}
宕机服务器高可用实现
说明:当服务器宕机时,如果访问时的失败次数达到最大失败次数,则标识为down.自动完成.在一定的周期之内,如果服务器恢复正常,则还会尝试访问故障机.
max_fails=1 最大的失败次数
fail_timeout=60s; 设定周期为60秒
upstream geteways {
#ip_hash;
server 192.168.227.131:8901 max_fails=1 fail_timeout=60s;
server 192.168.227.131:8902 max_fails=1 fail_timeout=60s;
server 192.168.227.131:8903 max_fails=1 fail_timeout=60s;
}
Nginx面试问题分析
为什么不采用多线程模型管理连接?
- 采用独立的进程,可以让互相之间不会影响。一个进程异常崩溃,其他进程的服务不会中断,提升了架构的可靠性。
- 进程之间不共享资源,不需要加锁,所以省掉了锁带来的开销。
为什么不采用多线程处理逻辑业务?
- 进程数已经等于核心数,再新建线程处理任务,只会抢占现有进程,增加切换代价。
- 作为接入层,基本上都是数据转发业务,网络 IO 任务的等待耗时部分,已经被处理为非阻塞/全异步/事件驱动模式,在没有更多 CPU 的情况下,再利用多线程处理,意义不大。并且如果进程中有阻塞的处理逻辑,应该由各个业务进行解决,比如 openResty 中利用了 Lua 协程,对阻塞业务进行了优化。