Docker-01
Dcoker: Docker 这个东西所扮演的角色,容易理解,它是一个容器引擎,也就是说实际上我们的容器最终是由Docker创建,运行在Docker中,其他相关的容器技术都是以Docker为基础,它是我们使用其他容器技术的核心。
docker安装
环境准备
#系统内核版本3.10以上
[root@localhost /]# uname -r
3.10.0-1062.el7.x86_64
#系统版本
[root@localhost /]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
[root@localhost /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
安装
帮助文档:
#需要gcc相关环境
yum -y install gcc
yum -y install gcc-c++
需要的安装包#删除旧版本的Docker
[root@localhost /]# yum -y remove docker \
> docker-client \
> docker-client-latest \
> docker-common \
> docker-latest \
> docker-latest-logrotate \
> docker-logrotate \
> docker-engine
Loaded plugins: fastestmirror
No Match for argument: docker
#备注: /var/lib/docker/ 下面的 容器,镜像,网络,磁盘卷 会被保留
#需要的安装包及gcc相关环境
yum -y install yum-utils
#设置镜像仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #默认是国外的
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #建议使用阿里云的镜像地址
#更新yum软件包索引
yum makecache fast
#安装docker docker-ce:社区版 ee企业版
yum -y install docker-ce docker-ce-cli containerd.io
yum -y install docker-ce docker-ce-cli containerd.io
#启动docker 启动报错查看是否下载完包
systemctl start docker
docker version
#阿里云加速器配置
[root@localhost docker]# cd /etc/docker/
[root@localhost docker]# touch daemon.json
[root@localhost docker]# cat daemon.json
{
"registry-mirrors":["https://alzgoonw.mirror.aliyuncs.com"]
}
[root@localhost docker]# systemctl restart docker
#测试hello world-world
docker run hello-world
注意:报错的话需要配置 阿里云镜像加速器。
了解:卸载docker
#卸载 依赖
yum -y remove docekr-ce docker-ce-cli containerd.io
# 删除资源
rm -rf /var/lib/docker docker默认工作目录
离线安装:
1.准备工作:
docker-20.10.14.tgz离线包下载地址:https://download.docker.com/linux/static/stable/x86_64/ 选择需要的docker版本
# 最终准备四个文件:
[root@K8s-node2 opt]# ll -h
total 62M
-rw-r--r-- 1 root root 62M Apr 20 14:14 docker-20.10.14.tgz
-rw-r--r-- 1 root root 1.2K Apr 20 14:20 docker.service
-rw-r--r-- 1 root root 495 Apr 20 14:15 install.sh
-rw-r--r-- 1 root root 214 Apr 20 14:16 uninstall.sh
------------------------ 创建docker.service文件 -------------------------------------
[root@K8s-node2 opt]# cat 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
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
------------------------- 创建install.sh脚本 -----------------------------------
[root@K8s-node2 opt]# cat install.sh
Docker常用命令
docker version # 查看docker版本信息
docker info #显示docker系统信息
docker()--help #帮助信息
查看帮助文档:
镜像命令
docker images 查看所有本地的主机上的镜像
[root@dockerYa ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat latest 9a9ad4f631f8 4 weeks ago 647MB
nginx latest 8cf1bfb43ff5 5 weeks ago 132MB
docker search 搜索镜像信息
docker search mysql --filter=STARS=3000 [root@dockerYa ~]# docker search mysql --filter=STARS=3000 NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 9911 [OK] mariadb MariaDB is a community-developed fork of MyS… 3627 [OK]
docker pull:下载镜像
#下载镜像 docker pull 镜像名[:tag] [root@dockerYa ~]# docker pull mysql
docker rmi 删除镜像
docker rmi -f 镜像ID docker rmi -f `(docker images -aq)` #删除所有镜像
容器命令
说明:有了镜像才有容器。
新建容器并启动
docker run [可选参数] image #参数说明 --name=“name” 容器名字 Tomcat01 Tomcat02 用来区分容器 -d 后来方式运行 -it 使用交互式方式运行,进入容器查看内容 -p 指定容器的端口 -p 8080:8090 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 -p 随机指定端口 docker run -it centos /bin/bash
列出当前运行的容器
# docker ps 命令 -a 列出当正在运行的容器+历史停用的容器 -n=? 显示最近创建的容器 -q 只显示容器的编号
退出容器
exit 退出并停止容器 CTRL + P + Q 容器不停止退出
删除容器
docker rm 容器ID 不能删除正在运行的容器 强制删除:rm -f docker rm -f `docker ps -aq` 删除所有容器
启动和停止容器
docker start 启动容器 docker restart 重启容器 docker stop 停止容器 docker kill 强制停止容器
常用的其他命令
后台启动容器
#命令 docker run -d centos
查看日志命令
docker logs -f -t --tail N [容器id] -tf 显示全部 --tail number 显示N条日志 # docker run -d centos /bin/bash -c "while true;do echo kobe kobe;sleep 1;done" docker ps docker logs -f -t --tail 10 [容器id]
查看容器中进程信息
# 命令 docekr top 容器ID
查看镜像源数据
# 命令 docker inspect 容器ID
进入当前正在运行的容器
# 命令 docker exec -it 容器ID /bin/bash 进入容器后 开启一个新的终端(常用) # docker attach 容器ID 进入正在执行的终端,不启动新的终端
容器内拷贝文件到主机
# docker cp 容器ID:/home/a.txt /home 拷贝是手动过程 后期 -v 容器卷
图命令
可视化
-
portainer (先用这个)
docker run -d -p 8080:9000 \ --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
-
Rancher(CI/CD再用)
什么是portainer?
Docker图形化界面管理工具!提供一个后台面板。
部署ES+kibana
# es 暴露端口很多 # es 十分耗内存 # es 的数据一般需要放置到安全目录! 挂载 # -- net somenetwork ? 网络配置 # 启动 elasticsearch docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 # 启动了 会卡 docker stats 查看 cpu 状态 # 测试一下 es 是否成功 [root@dockerYa ~]# curl localhost:9200 { "name" : "ee4a10ac7225", "cluster_name" : "docker-cluster", "cluster_uuid" : "EUVYW1eHTk6Q0WoMT6v1Tg", "version" : { "number" : "7.6.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f", "build_date" : "2020-03-26T06:34:37.794943Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" } # 赶紧关闭 增加内存的限制 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
commit镜像(入门)
docker commit 提交容器成为一个新的副本 #命令和Git原理类似 docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
#启动一个默认的Tomcat #发现这个默认的tomcat没有webapps应用, #自己拷贝进去了基本文件
容器数据卷
什么是容器数据卷
docker的理念
将应用和环境打包为一个镜像!
数据持久化,容器删除、数据就会丢失。(跑路?)
数据可以存储到本地,容器之间有一个数据共享技术,docker容器产生的数据,同步到本地!目录挂载、将容器的目录挂载在Linux上面。
容器的持久化和同步操作、容器间也是可以数据共享
方式一:直接使用命令挂载 -v
docker run -it -v 主机目录:容器内目录
测试!
以后修改就可以在本地修改即可。
具名挂载和匿名挂载
#匿名挂载 -v 容器内路径 docker run -d -p --name nginx01 -v /etc/nginx nginx #查看所有卷的情况 docker volume ls #这里发现,这种就是匿名挂载,我们在-v的时候 只写了容器内的路径,没有写容器外的路径。 #具名挂载 -v 卷名:容器内路径 docker run -d -p --name nginx02 -vjuming-nginx:/etc/nginx nginx #docker volume ls #查看卷路径 docker volume inspect juming0-nginx 具名gauzei可以方便的找到我们的卷,大多数使用具名挂载。 #指定路径挂载 -v /宿主机路径:容器内路径 #通过 -v 容器内路径 :ro rw 改变读写权限 ro readonly 只读 (只能通过宿主机来操作) rw readwrite 可读可写
初识Dockerfile
Dockerfile 就是用来构建docker镜像的构建文件!命令脚本!
通过脚本生成镜像,
#创建一个dockerfile文件、名称随机、建议dockerfile #文件中的内容 指令(大写) 参数 FROM centos VOLUME ["volume01","volume02"] CMD echo "----end----" CMD /bin/bash #这里的每个命令,就是镜像的一层! [root@dockerYa docker-test-volume]# docker build -f dockerfile01 -t mycentos:1.0 . Sending build context to Docker daemon 2.048kB Step 1/4 : FROM centos ---> 0d120b6ccaa8 Step 2/4 : VOLUME ["volume01","volume02"] ---> Using cache ---> f3c819fc7493 Step 3/4 : CMD echo "----end----" ---> Using cache ---> b0707582f94c Step 4/4 : CMD /bin/bash ---> Using cache ---> efb34e151925 Successfully built efb34e151925 Successfully tagged mycentos:1.0 [root@dockerYa docker-test-volume]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 1.0 54f49660f5bf 2 seconds ago 215MB redis latest 41de2cc0b30e 6 days ago 104MB nginx latest 4bb46517cac3 3 weeks ago 133MB centos latest 0d120b6ccaa8 4 weeks ago 215MB elasticsearch 7.6.2 f29a1ee41030 5 months ago 791MB #启动自己的容器 [root@dockerYa docker-test-volume]# docker run -it 54f49660f5bf /bin/bash [root@ee7d7712b1a4 /]# ls -l (查看挂载卷) total 0 lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin drwxr-xr-x. 5 root root 360 Sep 8 07:16 dev drwxr-xr-x. 1 root root 66 Sep 8 07:16 etc drwxr-xr-x. 2 root root 6 May 11 2019 home drwxr-xr-x. 2 root root 6 Sep 8 07:16 volume01 drwxr-xr-x. 2 root root 6 Sep 8 07:16 volume02 [root@dockerYa ~]# docker inspect ffdd27bce00d "Mounts": [ { "Type": "volume", "Name": "4998d9966ae9fdd7d4c8760dcec9b5faa79d93f324e0476b38cff1e6a82f35c6", "Source": "/var/lib/docker/volumes/4998d9966ae9fdd7d4c8760dcec9b5faa79d93f324e0476b38cff1e6a82f35c6/_data", "Destination": "volume02", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "f91989da2f2b1d6b595bd368643fc2cbe3b2b8fd199aacebd83e15006a0cdea2", "Source": "/var/lib/docker/volumes/f91989da2f2b1d6b595bd368643fc2cbe3b2b8fd199aacebd83e15006a0cdea2/_data", "Destination": "volume01", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } [root@dockerYa ~]# cd /var/lib/docker/volumes/f91989da2f2b1d6b595bd368643fc2cbe3b2b8fd199aacebd83e15006a0cdea2/_data [root@dockerYa _data]# ls container.txt **文件测试成功!** #这种方式使用十分多,会经常构建自己的镜像! 假设构建镜像时候没有挂载卷,需要手动挂载 -v 卷名:容器内路径
数据卷容器
多个mysql同步数据!
#获取mysql镜像: docker pull mysql:5.7 #运行容器,做数据挂载! 注意:安装启动mysql,需要配置密码。 docker run - d -p 3310:3306 -v /home/msyql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7 #启动成功后,使用本地SQLyog连接测试;ok !
#启动3个容器 docker run -it --name docker01 mycentos:1.0 #02数据卷挂载到01 docker run -it --name docker02 --volumes-from docker01 mycentos:1.0 #实现两个容器数据同步
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使为止。
但是一旦数据持久化到本地,这个时候本地的数据是不会删除的!
Dockerfile
dockerfile介绍:
dockerfile是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
-
编写一个dockerfile文件
-
docker build 构建成为一个镜像
-
docker run 运行镜像
-
docker push 发布镜像(DockerHub、阿里云镜像仓库)
官方镜像:
Dockerfile构建过程
基础知识:
-
每个保留的关键字(指令)必须是大写字母
-
执行从上到下顺序执行
-
(#)表示注释
-
每一个指令都会创建提交一个镜像层,并提交!
dockerfile是面向开发的,我们以后要发布项目,作镜像,就要编写dockerfile。
Docker镜像逐渐成为企业交付的标准,必须掌握!
步骤:开发、部署、运维。。。
dockerfile:构建文件,定义了一切的步骤,源代码
docker images: 通过dockerfile构建生成镜像,最终发布和运行的产品
docker容器:容器就是镜像运行起来提供服务器
dockerfile的指令
常用指令:
FROM #基础镜像 centos 。。 MAINTAINER #镜像是谁写的,姓名—邮箱 RUN #镜像构建的时候需要运行的命令 ADD #步骤:Tomcat镜像,这个tomcat压缩包。添加内容 WORKDIR #镜像的工作目录 VOLUME #挂载的目录 EXPOST #保留的端口配置 CMD #指定这个容器启动的时候需要运行的命令,只有最后一个命令会生效,可被替代。 ENRYPOINT #指定这个容器启动的时候需要运行的命令,可以追加命令 ONBUILD # 当构建一个被继承的dockerfile 这个时候就会运行onbuild指令,触发指令。 COPY #类似ADD,将文件拷贝到镜像中 ENV #构建时设置环环境变量。
测试:
创建一个自己的Centos
# 1:编写dockerfile的文件 [root@docker-angent_1 dockerfile]# cat mydockerfile-centos FROM centos MAINTAINER kobeqiang1278190430@qq.com ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "----end-----" CMD /bin/bash # 2:通过文件构建镜像 #命令 docker build -f dockerfile文件路径 -t 镜像名:[Tag] Successfully built c20beded6e33 Successfully tagged mycentos:1.0 # 3:测试运行、对比: #默认的: [root@38731bc19fe3 /]# pwd / [root@38731bc19fe3 /]# ifconfig bash: ifconfig: command not found [root@38731bc19fe3 /]# vim bash: vim: command not found [root@38731bc19fe3 /]# #增加后的: [root@docker-angent_1 dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 1.0 c20beded6e33 2 minutes ago 295MB mysql 5.7 d589ea3123e0 3 days ago 448MB centos 7 7e6257c9f8d8 4 weeks ago 203MB centos latest 0d120b6ccaa8 4 weeks ago 215MB [root@docker-angent_1 dockerfile]# docker run -it mycentos:1.0 [root@a7c875f9deb0 local]# pwd /usr/local [root@a7c875f9deb0 local]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet) RX packets 8 bytes 656 (656.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@a7c875f9deb0 local]# vim test
我们可以列出当前镜像变更的历史:
[root@docker-angent_1 dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos 1.0 c20beded6e33 9 minutes ago 295MB mysql 5.7 d589ea3123e0 3 days ago 448MB centos 7 7e6257c9f8d8 4 weeks ago 203MB centos latest 0d120b6ccaa8 4 weeks ago 215MB [root@docker-angent_1 dockerfile]# docker history c20beded6e33 IMAGE CREATED CREATED BY SIZE COMMENT c20beded6e33 9 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B 8742ea6daf2b 9 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 6948ab4a68df 9 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 82af7c7bae1a 9 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B 0bf010f9501d 9 minutes ago /bin/sh -c yum -y install net-tools 22.8MB a9b24b62f637 9 minutes ago /bin/sh -c yum -y install vim 57.2MB 35577f90fe90 9 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B d38edae96079 9 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B bfea141b46e4 9 minutes ago /bin/sh -c #(nop) MAINTAINER kobeqiang12781… 0B 0d120b6ccaa8 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 4 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:538afc0c5c964ce0d… 215MB
CMD和ENTRYPOINT的区别
CMD #指定这个容器启动的时候需要运行的命令,只有最后一个命令会生效,可被替代。 ENRYPOINT #指定这个容器启动的时候需要运行的命令,可以追加命令
测试cmd
# 编写dockerfile文件 [root@docker-angent_1 dockerfile]# cat dockerfile-CMD FROM centos CMD ["ls","-a"] #构建镜像: [root@docker-angent_1 dockerfile]# docker build -f dockerfile-CMD -t cmdtest . Successfully built 2b765e586e71 Successfully tagged cmdtest:latest #run 运行 发现ls -a 命令生效 [root@docker-angent_1 dockerfile]# docker run cmdtest . .. .dockerenv bin dev etc home lib #想追加一个命令 -l、发现报错、而ls -al 则成功。 #CMD 情况下 -l替换了CMD["ls","-a"]命令 [root@docker-angent_1 dockerfile]# docker run cmdtest -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown. [root@docker-angent_1 dockerfile]# docker run cmdtest ls -al total 0 drwxr-xr-x. 1 root root 6 Sep 8 13:46 . drwxr-xr-x. 1 root root 6 Sep 8 13:46 .. -rwxr-xr-x. 1 root root 0 Sep 8 13:46 .dockerenv lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
测试 ENTRYPOINT
[root@docker-angent_1 dockerfile]# docker build -f dockerfile-entrypoint -t entry-test . Sending build context to Docker daemon 4.096kB Step 1/2 : FROM centos ---> 0d120b6ccaa8 Step 2/2 : ENTRYPOINT ["ls","-a"] ---> Running in 338ed757f0c3 Removing intermediate container 338ed757f0c3 ---> 97f41a603ec6 Successfully built 97f41a603ec6 Successfully tagged entry-test:latest [root@docker-angent_1 dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE entry-test latest 97f41a603ec6 37 seconds ago 215MB cmdtest latest 2b765e586e71 11 minutes ago 215MB [root@docker-angent_1 dockerfile]# docker run entry-test dev etc home [root@docker-angent_1 dockerfile]# docker run entry-test -l total 0 drwxr-xr-x. 1 root root 6 Sep 8 13:52 . drwxr-xr-x. 1 root root 6 Sep 8 13:52 .. # 发现ENTRYPOINT命令 可以追加-l
实战:tomcat镜像
-
准备镜像文件Tomcat压缩包、jdk的压缩包
[root@localhost tomcat]# pwd /home/tomcat [root@localhost tomcat]# ll total 150712 -rw-r--r--. 1 root root 11211292 Sep 9 15:03 apache-tomcat-9.0.37.tar.gz -rw-r--r--. 1 root root 143111803 Sep 9 15:26 jdk-8u261-linux-x64.tar.gz
-
编写dockerfile文件,官方命名Dockerfile,build 会自动寻找这个文件,就不需要-f指定了。
FROM centos MAINTAINER kobeqinag<> COPY readme.txt /usr/local/readme.txt ADD jdk-8u261-linux-x64.tar.gz /usr/local ADD apache-tomcat-9.0.37.tar.gz /usr/local RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_261 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.37 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/ca talina.out
-
构建镜像
#构建镜像 [root@localhost tomcat]# docker build -t mytomcat . [root@localhost tomcat]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat latest c2e2336760d0 7 minutes ago 640MB centos latest 0d120b6ccaa8 4 weeks ago 215MB hello-world latest bf756fb1ae65 8 months ago 13.3kB #启动镜像、访问测试、 [root@localhost tomcat]# docker run -d -p 9090:8080 --name tomcat_01_alt -v /home/tomcat/alt:/usr/local/apache-tomcat-9.0.37/webapps/alt -v /home/tomcat/tomcat_alt_logs:/usr/local/apache-tomcat-9.0.37/logs dqgx-tomcat [root@localhost ~]# curl localhost:9090 <!DOCTYPE html> <html lang="en">
发布项目(做了卷挂载、本地操作)
[root@localhost test]# pwd /home/tomcat/test [root@localhost test]# ls index.jsp WEB-INF [root@localhost test]# cd WEB-INF/ [root@localhost WEB-INF]# ls web.xml
#web.xml [root@localhost WEB-INF]# cat web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> </web-app>
[root@localhost test]# pwd /home/tomcat/test [root@localhost test]# ls (注意index.jsp 与 web.xml文件的位置) index.jsp WEB-INF [root@localhost test]# cat index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello-阿强</title> </head> <body> Hello World!<br/> <% System.out.println("----my test web logs----"); %> </body> </html>
项目发布成功可以直接访问
发布自己的镜像
DockerHub
-
注册DockerHub账户https://hub.docker.com
-
确定这个账户可以登录
-
在自己的服务器上提交自己的镜像
[root@localhost test]# docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username [root@localhost test]# docker login -u kobeqiang Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
-
登录完毕后就可以提交镜像了、docker push
[root@localhost tomcat]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat 1.1 c2e2336760d0 58 minutes ago 640MB mytomcat latest c2e2336760d0 58 minutes ago 640MB centos latest 0d120b6ccaa8 4 weeks ago 215MB #push报错、 [root@localhost tomcat]# docker push kobeqiang/mytomcat:1.1 The push refers to repository [docker.io/kobeqiang/mytomcat] An image does not exist locally with the tag: kobeqiang/mytomcat #解决、增加一个Tag [root@localhost tomcat]# docker tag c2e2336760d0 kobeqiang/tomcat:1.0 [root@localhost tomcat]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mytomcat latest c2e2336760d0 About an hour ago 640MB kobeqiang/tomcat 1.0 c2e2336760d0 About an hour ago 640MB #docker push 上去成功!注意:自己发布的镜像要带上版本号 [root@localhost tomcat]# docker push kobeqiang/tomcat:1.0 The push refers to repository [docker.io/kobeqiang/tomcat] 22890905b57c: Pushed fc6c3a9a742b: Pushed 2fea3826ffdc: Pushed 8be62079cae0: Pushed 291f6e44771a: Mounted from library/centos 1.0: digest: sha256:a76aaae4afc72ece0853c60bb5a8d78fee1060b341a8308c547fbb62017f3dec size: 1373 #提交的时候也是按照镜像一层一层提交的。 #退出: [root@localhost tomcat]# docker logout Removing login credentials for https://index.docker.io/v1/
发布到阿里云镜像服务上
-
登录阿里云
-
找到容器镜像服务
-
创建命名空间
-
创建容器镜像
-
查看信息
-
根据阿里云文档进行操作、
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE kobeqiang/tomcat 1.0 c2e2336760d0 2 hours ago 640MB mytomcat 1.1 c2e2336760d0 2 hours ago 640MB mytomcat latest c2e2336760d0 2 hours ago 640MB [root@localhost ~]# docker tag c2e2336760d0 registry.cn-beijing.aliyuncs.com/kobeqiang/kobeqiang-test:1.0 [root@localhost ~]# docker push registry.cn-beijing.aliyuncs.com/kobeqiang/kobeqiang-test:1.0 The push refers to repository [registry.cn-beijing.aliyuncs.com/kobeqiang/kobeqiang-test] 22890905b57c: Pushed fc6c3a9a742b: Pushed 2fea3826ffdc: Pushed 8be62079cae0: Pushed 291f6e44771a: Pushed 1.0: digest: sha256:a76aaae4afc72ece0853c60bb5a8d78fee1060b341a8308c547fbb62017f3dec size: 1373
-
push阿里云成功!
-
小结:
Docker网络 (铺垫 容器编排 集群部署!)
理解Docker0网络
清空所有环境
测试
三个网络
#问题: docker 是如何处理容器网络访问的?
# 启动容器 [root@localhost ~]# docker run -d -P --name tomcat1 tomcat #查看容器内部网络地址、ip addr 。发现容器启动会分配到一个eth0的ip地址。 root@localhost ~]# docker exec -it 60ac72339c27 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever #思考 linux能不能ping通容器内部 [root@localhost ~]# ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.066 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.088 ms # linux可以ping通 docker 容器内部。
原理
-
每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0桥接模式,使用的技术就是veth-pair技术!
再次测试ip addr
-
在启动一个容器测试,发现又多了一对网卡
#我们发现这个容器带来的网卡,都是一对对的 #veth-pair 就是一对的虚拟设备接口,他们都是成对出现的。一段连着协议,一段彼此相连 #正因为有这个特性,veth-pair 充当一个桥梁,连接各种虚拟网络设备的。
-
测试 Tomcat1和tomcat2能否ping通?
[root@localhost ~]# docker exec -it tomcat2 ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.060 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.099 ms ^C --- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.060/0.079/0.099/0.021 ms # 容器和容器之间是可以互相ping通的!
原理图:
结论: tomcat1和tomcat2 是公用的一个路由,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给容器分配一个默认的可用ip。
小结
Docker 使用的是Linux的桥接,宿主机中是一个Docker容器的网桥docker0.
Docker中的所有网络接口都是虚拟的,虚拟的转发效率高!(内网传递文件!)
只要容器一删除,对应网桥就没了。
--link
思考一个场景,我们编写了一个微服务,database url=ip:,项目不重启,数据库ip换掉了,我们希望可以处理这个问题,可以名字来进行访问容器?
[root@localhost ~]# docker exec -it tomcat2 ping tomcat1 ping: tomcat1: Name or service not known #如何解决? #通过--link 既可以解决了网络连通问题 [root@localhost ~]# docker run -d -P --name tomcat3 --link tomcat2 tomcat da8ff297e3e38fcc7cf565f0b3dff64568b05d8b6b93d7ebc97a2e34035acce4 [root@localhost ~]# docker exec -it tomcat3 ping tomcat2 PING tomcat2 (172.17.0.3) 56(84) bytes of data. 64 bytes from tomcat2 (172.17.0.3): icmp_seq=1 ttl=64 time=0.065 ms 64 bytes from tomcat2 (172.17.0.3): icmp_seq=2 ttl=64 time=0.099 ms # 反向可以ping通么? [root@localhost ~]# docker exec -it tomcat2 ping tomcat3 ping: tomcat3: Name or service not known
探究:inspect
其实这个tomcat3就是在本地配置了tomcat2的解析
#查看hosts配置,发现原理。 [root@localhost ~]# docker exec -it tomcat3 cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 tomcat2 31956372a41f 172.17.0.4 da8ff297e3e3
本质探究:--link就是在hosts配置中增加了一个 172.17.0.3 tomcat2 31956372a41f
现在docker已经不建议使用--link了!
自定义网络! 不适用docker0!
docker0问题: 他不支持容器名连接访问!
自定义网络
查看所有的docker网络
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 73eaa41413b8 bridge bridge local 05f6a4c7b08f host host local bf5d00f9b198 none null local
网络模式
bridge : 桥接 docker上搭桥 (默认)
none : 不配置网络
host : 和宿主机共享网络
container: 容器网络连通!(用的少。局限很大)
测试
#我们直接启动的命令 --net bridge , 这个就是我们的docker0 docker run -d -P --name tomcat01 tomcat docker run -d -P --name tomcat01 --net bridge tomcat # docker0特点: 默认 域名不能访问,--link 可以打通,不建议。 #我们可以自定义一个网络 #--driver bridge #--subnet 192.168.0.0/16 #--gateway 192.168.0.1 [root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 0833b39ff4a0940e99d56857c200b1272ad8abb36d447c19417aaa016c9951a5 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 73eaa41413b8 bridge bridge local 05f6a4c7b08f host host local 3f192473e4fb mynet bridge local
查看创建的网络:docker network inspect mynet
#创建容器加入自定义网络 [root@localhost ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat ca9c3187931330417728f05d383bb8b5aa28412d678b8890575fa3e78f703351 [root@localhost ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat 09a16147ec07c3b4c43e85e2da27356433e5ce6c4bdfff5f4529c2122ad5cfb9 [root@localhost ~]# docker network inspect mynet [ { "Name": "mynet", "Id": "0833b39ff4a0940e99d56857c200b1272ad8abb36d447c19417aaa016c9951a5", "Created": "2020-09-10T10:51:59.117048253+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "09a16147ec07c3b4c43e85e2da27356433e5ce6c4bdfff5f4529c2122ad5cfb9": { "Name": "tomcat-net02", "EndpointID": "982c0cb4174bc84e983f82add9c199436886187baa9e9b25a25d4b9d12e731c4", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" }, "ca9c3187931330417728f05d383bb8b5aa28412d678b8890575fa3e78f703351": { "Name": "tomcat-net01", "EndpointID": "6be67748f5a3b7df2f4bdef1b505dfd1df2ec81d9d2673675c6b411a2c6deeda", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] #再次测试ping、 [root@localhost ~]# docker exec -it tomcat-net01 ping 192.168.0.3 PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data. 64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.055 ms 64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.170 ms #现在不使用--link也可以ping通名字 [root@localhost ~]# docker exec -it tomcat-net01 ping tomcat-net02 PING tomcat-net02 (192.168.0.3) 56(84) bytes of data. 64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.103 ms 64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.100 ms
我们自定义的网络docker可以帮我们维护好对应关系,推荐使用自定义网络!
网络连通
[root@localhost ~]# docker network --help Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network create Create a network disconnect Disconnect a container from a network inspect Display detailed information on one or more networks ls List networks prune Remove all unused networks rm Remove one or more networks [root@localhost ~]# docker network connect --help Usage: docker network connect [OPTIONS] NETWORK CONTAINER Connect a container to a network Options: --alias strings Add network-scoped alias for the container --driver-opt strings driver options for the network --ip string IPv4 address (e.g., 172.30.100.104) --ip6 string IPv6 address (e.g., 2001:db8::33) --link list Add link to another container --link-local-ip strings Add a link-local address for the container [root@localhost ~]#
#测试 打通 tomcat01 - mynet [root@localhost ~]# docker network connect mynet tomcat01 #连通之后就是将 tomcat01 放到了 mynet 网络下、 #一个容器两个 ip 地址。阿里云:公网ip 私网ip [root@localhost ~]# docker network inspect mynet [ "Name": "mynet", "Scope": "local", "Driver": "bridge" "Subnet": "192.168.0.0/16", "Gateway": "192.168.0.1" "982c0cb4174bc84e983f82add9c199436886187baa9e9b25a25d4b9d12e731c4", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" }, "68adf2d6db267c529c07a831771b387616deb308fe1a68ec3ae5c5320bd62c79": { "Name": "tomcat01", "EndpointID": "7d95ff4db6303a1e822d769df20dd51c7bbc13fe9cd53b38690224de2c1b62f0", "MacAddress": "02:42:c0:a8:00:04", "IPv4Address": "192.168.0.4/16", "IPv6Address": "" }, "ca9c3187931330417728f05d383bb8b5aa28412d678b8890575fa3e78f703351": { "Name": "tomcat-net01", "EndpointID": "6be67748f5a3b7df2f4bdef1b505dfd1df2ec81d9d2673675c6b411a2c6deeda", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" } #测试tomcat01能否ping通 [root@localhost ~]# docker exec -it tomcat01 ping tomcat-net01 PING tomcat-net01 (192.168.0.2) 56(84) bytes of data. 64 bytes from tomcat-net01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.078 ms 64 bytes from tomcat-net01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.098 ms #tomcat02 依旧不通 [root@localhost ~]# docker exec -it tomcat02 ping tomcat-net01 ping: tomcat-net01: Name or service not known
结论:假设要跨网络操作别人,就需要使用docker network connect 连通!。。
实战:部署Redis集群
shell脚本!
#创建Redis网络 [root@localhost ~]# docker network create --subnet 172.38.0.0/16 redis c7464eb062357a03a75275e37e50e13cc4f113806bbb59a880a8835ca65e008e [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 73eaa41413b8 bridge bridge local 05f6a4c7b08f host host local c7464eb06235 redis bridge local #通过脚本创建6个Redis配置 for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >/mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done #脚本启动节点/同创建redis配置一起用 docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} -v /mydata/redis/node-${port}/data:/data -v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf #分别启动六个node节点/1-6 [root@localhost ~]# docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /mydata/redis/node-1/data:/data -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf [root@localhost ~]# docker run -p 6376:6379 -p 16376:16379 --name redis-6 -v /mydata/redis/node-6/data:/data -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf #创建集群的配置 [root@localhost ~]# docker exec -it redis-1 /bin/sh /data # ls appendonly.aof nodes.conf /data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1 >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 172.38.0.15:6379 to 172.38.0.11:6379 Adding replica 172.38.0.16:6379 to 172.38.0.12:6379 Adding replica 172.38.0.14:6379 to 172.38.0.13:6379 M: a0517457e11a0864acf3c3b926f1f91ceac91e12 172.38.0.11:6379 slots:[0-5460] (5461 slots) master M: 3ff653ff4cf7675dba9cb589afcda22887bd08f1 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master M: 200d88d03dc389f09185107dc7e6b818849f2847 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master S: 1e932f4c62cff89381217d4bdb75122af7d54f7d 172.38.0.14:6379 replicates 200d88d03dc389f09185107dc7e6b818849f2847 S: 811d492546458c922338ce98c9015aa423897de2 172.38.0.15:6379 replicates a0517457e11a0864acf3c3b926f1f91ceac91e12 S: 9dfa8b6b77cf1b95ebec69a64cc363e85b361a75 172.38.0.16:6379 replicates 3ff653ff4cf7675dba9cb589afcda22887bd08f1 Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node 172.38.0.11:6379) M: a0517457e11a0864acf3c3b926f1f91ceac91e12 172.38.0.11:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: 9dfa8b6b77cf1b95ebec69a64cc363e85b361a75 172.38.0.16:6379 slots: (0 slots) slave replicates 3ff653ff4cf7675dba9cb589afcda22887bd08f1 M: 3ff653ff4cf7675dba9cb589afcda22887bd08f1 172.38.0.12:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: 811d492546458c922338ce98c9015aa423897de2 172.38.0.15:6379 slots: (0 slots) slave replicates a0517457e11a0864acf3c3b926f1f91ceac91e12 M: 200d88d03dc389f09185107dc7e6b818849f2847 172.38.0.13:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: 1e932f4c62cff89381217d4bdb75122af7d54f7d 172.38.0.14:6379 slots: (0 slots) slave replicates 200d88d03dc389f09185107dc7e6b818849f2847 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1 # /data # redis-cli -c 127.0.0.1:6379> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:1287 cluster_stats_messages_pong_sent:1309 cluster_stats_messages_sent:2596 cluster_stats_messages_ping_received:1304 cluster_stats_messages_pong_received:1287 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:2596 127.0.0.1:6379> cluster nodes a0517457e11a0864acf3c3b926f1f91ceac91e12 172.38.0.11:6379@16379 myself,master - 0 1599716363000 1 connected 0-5460 9dfa8b6b77cf1b95ebec69a64cc363e85b361a75 172.38.0.16:6379@16379 slave 3ff653ff4cf7675dba9cb589afcda22887bd08f1 0 1599716364887 6 connected 3ff653ff4cf7675dba9cb589afcda22887bd08f1 172.38.0.12:6379@16379 master - 0 1599716364000 2 connected 5461-10922 811d492546458c922338ce98c9015aa423897de2 172.38.0.15:6379@16379 slave a0517457e11a0864acf3c3b926f1f91ceac91e12 0 1599716365395 5 connected 200d88d03dc389f09185107dc7e6b818849f2847 172.38.0.13:6379@16379 master - 0 1599716364379 3 connected 10923-16383 1e932f4c62cff89381217d4bdb75122af7d54f7d 172.38.0.14:6379@16379 slave 200d88d03dc389f09185107dc7e6b818849f2847 0 1599716364582 4 connected #测试 127.0.0.1:6379> set a b -> Redirected to slot [15495] located at 172.38.0.13:6379 OK 172.38.0.13:6379> get a "b" #把172.38.0.13即Redis-3节点停止、然后get a 172.38.0.13:6379> get a ^C /data # redis-cli -c 127.0.0.1:6379> get a -> Redirected to slot [15495] located at 172.38.0.14:6379 "b" #查看、搭建成功。 172.38.0.14:6379> cluster nodes 9dfa8b6b77cf1b95ebec69a64cc363e85b361a75 172.38.0.16:6379@16379 slave 3ff653ff4cf7675dba9cb589afcda22887bd08f1 0 1599717001507 6 connected 200d88d03dc389f09185107dc7e6b818849f2847 172.38.0.13:6379@16379 master,fail - 1599716762868 1599716762563 3 connected a0517457e11a0864acf3c3b926f1f91ceac91e12 172.38.0.11:6379@16379 master - 0 1599717002000 1 connected 0-5460 1e932f4c62cff89381217d4bdb75122af7d54f7d 172.38.0.14:6379@16379 myself,master - 0 1599717000000 7 connected 10923-16383 3ff653ff4cf7675dba9cb589afcda22887bd08f1 172.38.0.12:6379@16379 master - 0 1599717003638 2 connected 5461-10922 811d492546458c922338ce98c9015aa423897de2 172.38.0.15:6379@16379 slave a0517457e11a0864acf3c3b926f1f91ceac91e12 0 1599717002623 5 connected
docker搭建Redis集群成功!
SpeingBoot微服务打包Docker镜像
-
构建springboot项目
-
打包项目
-
编写dockerfile
From java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
-
构建镜像
-
发布运行
以后我们使用了Docker之后,给别人交付的就是一个镜像即可!
docker01完结
??如果有很多镜像?、1000个镜像?、
Docker 进阶
准备工作:安装docker
同基础上
Docker Compose
Docker-Compose(优缺点) Docker-Compose 是用来管理你的容器的,有点像一个容器的管家,想象一下当你的Docker中有成百上千的容器需要启动,如果一个一个的启动那得多费时间。有了Docker-Compose你只需要编写一个文件,在这个文件里面声明好要启动的容器,配置一些参数,执行一下这个文件,Docker就会按照你声明的配置去把所有的容器启动起来,但是Docker-Compose只能管理当前主机上的Docker,也就是说不能去启动其他主机上的Docker容器
docker compose 来轻松高效管理容器。定义运行多个容器。
作用:批量容器编排。
compose是官方的开源项目,需要安装!
Compose :重要的概念
-
服务services,容器,应用,(web/redis/mys,,)
-
项目 project。 一组关联的容器,博客,web,mysql,wp。
安装compose
1、下载
#官网 curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose #这个可能会快点?? curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
2、安装成功
多看官网!!
3、体验
地址:https://docs.docker.com/compose/gettingstarted/
通过Docker Compose上构建一个简单的Python web应用程序,使用Flask框架并在Redis中维护一个计数器,用来记录改web应用被访问的次数。
1、准备工作
yum -y install python-pip #pip是Python 包管理工具 yum -y install epel-release #报错执行安装依赖
2、为项目创建目录
mkdir composetest cd -
3、在项目目录中创建一个名为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)
4、在项目目录中创建另一个名为requirements.txt的文件
flask redis
5、在项目目录中,创建名为Dockerfile的文件:
FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt EXPOSE 5000 COPY . . CMD ["flask", "run"] # CMD ["python", "app.py"] #从Python 3.7映像开始构建映像。 #将工作目录设置为/code。 #设置flask命令使用的环境变量。 #安装gcc和其他依赖项 #复制requirements.txt并安装Python依赖项。 #向图像添加元数据以描述容器正在侦听端口5000 #将.项目中的当前目录复制到.映像中的工作目录。 #将容器的默认命令设置为flask run。
6、在项目目录中创建一个名为docker-compose.yml的文件:
#定义了两个服务:web和redis version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
大概流程:
-
应用 app.py
-
Dockerfile 将应用打包为镜像
-
Docker-compose yaml 文件(定义整个服务,需要的一些环境。web/redis)完整的上线服务
-
启动 compose 项目 (docker-compose up)
流程:
-
创建网络
-
执行 Docker-compose yaml
-
启动服务:(很慢)
-
Creating composetest_redis_1 ... done Creating composetest_web_1 ... done
-
-
文件名 composetest
version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
自动默认规则
测试成功!
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 188f23975dd3 composetest_web "flask run" 58 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp composetest_web_1 8fe4249f2093 redis:alpine "docker-entrypoint.s…" 58 minutes ago Up 2 minutes 6379/tcp composetest_redis_1 [root@localhost ~]# curl localhost:5000 Hello World! I have been seen 5 times. [root@localhost ~]# curl localhost:5000 Hello World! I have been seen 6 times. [root@localhost ~]# curl localhost:5000 Hello World! I have been seen 7 times.
[root@localhost ~]# docker service ls Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
默认的服务名 文件名-服务名-num
多个服务器 集群 A B _num 副本数量
服务redis服务=>4个副本
集群状态,弹性、HA 高并发 (kubetctl service 负载均衡)
网络规则:
10个服务=》项目 (项目中的内容都在同一个网络下,域名访问 )
如果在同一网络下,可以通过域名来访问。HA!
停止:docker-compose down(在对应的文件下) 或者: Ctrl+C
Docker-Compose
以前都是单个docker run 启动容器
docker-compose、通过docker-compose编写yaml配置文件、可以通过compose一键启动所有服务,停止!
Docker小结:
-
Docker镜像,run=》容器
-
Dockerfile构建镜像 (服务打包)
-
Docker-Compose启动项目(编排、多个微服务/环境)
-
Docker网络!
-
Yaml规则:
docker-compose.yaml 核心
官方文档地址:https://docs.docker.com/compose/compose-file
# 3层 version: #版本 1 向下兼容 services: #服务 2 服务1: web #服务配置 images build network .... 服务2:Redis ... #其他配置 网络/卷、全局规则 3 networks vloume configs ......
多写,多练,多看,compose.yaml文件!官方文档 、开源项目。
开源项目(博客)
下载程序、安装数据库、配置......
compose 应用=>一键启动!
-
下载项目(docker-compose.yaml)
-
如果需要文件。Dockerfile
-
文件准备齐全(直接一键启动项目)
# 1、创建一个空的项目目录my_wordpress,并进入目录; [root@localhost home]# mkdir my_wordpress [root@localhost home]# cd my_wordpress # 2、创建一个docker-compose.yml文件来启动您的 WordPress博客,并创建一个单独的MySQL实例,该实例具有用于数据持久性的卷挂载: version: '3.3' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: db_data: {} #Docker卷db_data将WordPress所做的所有更新持久化到数据库。WordPress Multisite仅适用于port 80和443。 3、启动docker-compose up [root@localhost my_wordpress]# docker-compose up Status: Downloaded newer image for wordpress:latest Creating my_wordpress_db_1 ... done Creating my_wordpress_wordpress_1 ... done Attaching to my_wordpress_db_1, my_wordpress_wordpress_1 [root@localhost composetest]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6d0cc0d74fd6 wordpress:latest "docker-entrypoint.s…" 31 seconds ago Up 30 seconds 0.0.0.0:8000->80/tcp my_wordpress_wordpress_1 cc754e2eae77 mysql:5.7 "docker-entrypoint.s…" 32 seconds ago Up 31 seconds 3306/tcp, 33060/tcp my_wordpress_db_1 a86d12bfa37e mysql:5.7 "docker-entrypoint.s…" 3 days ago Up 3 days 0.0.0.0:3306->3306/tcp, 33060/tcp dq-mysql
前台启动 : docker -d 、docker-compose up -d
[root@localhost my_wordpress]# docker-compose up -d Starting my_wordpress_db_1 ... done Starting my_wordpress_wordpress_1 ... done
一切都很简单!
掌握:docker基础,原理,网络,服务,集群,错误排查,日志。
linux docker k8s
总结:
工程、服务、容器
项目compose:三层
-
工程Project
-
服务 services
-
容器 运行实例
Docker Swarm
Docker Swarm 是一款用来管理多主机上的Docker容器的工具,可以负责帮你启动容器,监控容器状态,如果容器的状态不正常它会帮你重新帮你启动一个新的容器,来提供服务,同时也提供服务之间的负载均衡,而这些东西Docker-Compose 是做不到的
集群方式的部署
-
准备四台安装Docker的服务器
搭建集群:
私网、公网
初始化节点(创建)
# docker swarm init 初始化节点 #--advertise-addr 地址 [root@Docker-01 ~]# docker swarm init --advertise-addr 192.168.1.99
#获取令牌 docker swarm join-token manager #管理节点 docker swarm join-token worker #工作节点 [root@Docker-01 ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-6cfhg4y3yyix3ba3bgnb66vzmcwnn61sj3f36bou11xn3e3ioz-bdxtj1xp5po6qmx3s1fu0hzhg 192.168.1.99:2377 #2和3加入管理节点1 [root@Docker-01 ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-6cfhg4y3yyix3ba3bgnb66vzmcwnn61sj3f36bou11xn3e3ioz-bdxtj1xp5po6qmx3s1fu0hzhg 192.168.1.99:2377 #查看: [root@Docker-01 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nlccevd2kp3ddcvzealrcimh9 * Docker-01 Ready Active Leader 19.03.12 dlkzlvvsurcf62pir2efu05p7 Docker-02 Ready Active 19.03.12 mzzag5vqlqws94123kk9t58pw Docker-03 Ready Active 19.03.12 #将04加入并管理节点 [root@Docker-01 ~]# docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-6cfhg4y3yyix3ba3bgnb66vzmcwnn61sj3f36bou11xn3e3ioz-d6114b887g9byls2mzo4feaeg 192.168.1.99:2377 [root@Docker-04 ~]# docker swarm join --token SWMTKN-1-6cfhg4y3yyix3ba3bgnb66vzmcwnn61sj3f36bou11xn3e3ioz-d6114b887g9byls2mzo4feaeg 192.168.1.99:2377 This node joined a swarm as a manager. #再次查看 [root@Docker-01 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nlccevd2kp3ddcvzealrcimh9 * Docker-01 Ready Active Leader 19.03.12 dlkzlvvsurcf62pir2efu05p7 Docker-02 Ready Active 19.03.12 mzzag5vqlqws94123kk9t58pw Docker-03 Ready Active 19.03.12 npw27mywz4g60ueh2f3m57rso Docker-04 Ready Active Reachable 19.03.12 #两个管理节点 两个工作节点()一般管理节点是3+台、奇数
-
生成主节点 init
-
加入(管理、工作节点)
Raft协议
双主双从:假设一个节点挂了,其他节点是否可用?
Raft协议:保证大多数节点存活才可以用。集群至少>3台。
实验:(基本命令操作)
-
将主节点docker-01服务停掉,查看另外一主节点(04节点)是否可用?(双主)
[root@Docker-01 ~]# systemctl stop docker [root@Docker-04 ~]# docker node ls Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded
-
发现另一主节点不可用
-
将03节点离开集群、查看发现显示Down
[root@Docker-03 ~]# docker swarm leave Node left the swarm. [root@Docker-04 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nlccevd2kp3ddcvzealrcimh9 Docker-01 Ready Active Reachable 19.03.12 dlkzlvvsurcf62pir2efu05p7 Docker-02 Ready Active 19.03.12 mzzag5vqlqws94123kk9t58pw Docker-03 'Down' Active 19.03.12 npw27mywz4g60ueh2f3m57rso * Docker-04 Ready Active Leader 19.03.12
-
把03加入设置为管理节点
#获取管理节点令牌 [root@Docker-01 ~]# docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-6cfhg4y3yyix3ba3bgnb66vzmcwnn61sj3f36bou11xn3e3ioz-d6114b887g9byls2mzo4feaeg 192.168.1.99:2377 #加入集群设置管理节点 [root@Docker-03 ~]# docker swarm join --token SWMTKN-1-6cfhg4y3yyix3ba3bgnb66vzmcwnn61sj3f36bou11xn3e3ioz-d6114b887g9byls2mzo4feaeg 192.168.1.99:2377 This node joined a swarm as a manager. #03节点测试 [root@Docker-03 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nlccevd2kp3ddcvzealrcimh9 Docker-01 Ready Active Reachable 19.03.12 dlkzlvvsurcf62pir2efu05p7 Docker-02 Ready Active 19.03.12 mzzag5vqlqws94123kk9t58pw Docker-03 Down Active 19.03.12 qy9su0bul9kqp7qxpzlija3s4 * Docker-03 Ready Active Reachable 19.03.12 npw27mywz4g60ueh2f3m57rso Docker-04 Ready Active Leader 19.03.12
-
work就是工作的、管理节点操作、3台机器设置为主节点
-
现在再把01主节点停掉、查看另外两个主节点是否可用、
[root@Docker-01 ~]# systemctl stop docker [root@Docker-03 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nlccevd2kp3ddcvzealrcimh9 Docker-01 Ready Active 'Unreachable' 19.03.12 dlkzlvvsurcf62pir2efu05p7 Docker-02 Ready Active 19.03.12 mzzag5vqlqws94123kk9t58pw Docker-03 Down Active 19.03.12 qy9su0bul9kqp7qxpzlija3s4 * Docker-03 Ready Active Reachable 19.03.12 npw27mywz4g60ueh2f3m57rso Docker-04 Ready Active Leader 19.03.12 #发现03和04主节点依旧可用、
-
现在再把03停用、04是否可用?
[root@Docker-03 ~]# systemctl stop docker [root@Docker-04 ~]# docker node ls Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online. #发现不可用、需要等一下,有延迟
总结:集群,可用! 3个主节点。。
Raft协议:保证大多数节点存活,才能使用,高可用!
弹性、扩缩容!
体会弹性、扩缩容!
以后告别docker run !
docker-compose up! 启动一个项目,单机!
集群: swarm docker service
容器=》服务! =>副本!
redis=3 !容器 、集群:高可用,web->redis(3台分布不同主机上)
体验:创建服务、动态扩展服务、动态更新服务。
[root@Docker-01 ~]# docker service --help Usage: docker service COMMAND Manage services Commands: create Create a new service inspect Display detailed information on one or more services logs Fetch the logs of a service or task ls List services ps List the tasks of one or more services rm Remove one or more services rollback Revert changes to a service's configuration scale Scale one or multiple replicated services update Update a service Run 'docker service COMMAND --help' for more information on a command.
灰度发布:金丝雀发布!
启动一个服务:
# docker run 容器启动、 不具有扩缩容器 # docker service 服务! 具有扩缩容、滚动更新! [root@Docker-01 ~]# docker service create -p 8888:80 --name my-nginx nginx d2gtohwwxwszny9j4eflwnzbc overall progress: 1 out of 1 tasks 1/1: running verify: Service converged #查看服务副本 docker service ps 服务名字 或者: docker service ls 或者 inspect 服务名 [root@Docker-01 ~]# docker service ps my-nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS sv3vzpdg8ft3 my-nginx.1 nginx:latest Docker-03 Running Running 53 seconds ago #发现启动的一个服务副本在03上,随机分配
访问量大了-扩展副本,以及服务副本缩容。
#扩展3个副本 [root@Docker-01 ~]# docker service update --replicas 3 my-nginx my-nginx overall progress: 3 out of 3 tasks 1/3: running 2/3: running 3/3: running verify: Service converged #发现访问任意一个节点 都能访问! 若不行 就重启该节点服务 restart docker #服务副本缩容 [root@Docker-01 ~]# docker service update --replicas 1 my-nginx my-nginx overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged #发现所有节点只剩一个副本。ps -a 也没有。棒a! 依旧所有节点可以访问!
{docker service scale my-nginx=5} 等于 {docker service update --replicas 5 my-nginx}
删除服务:docker service rm my-nginx (移除)
服务,集群中的任意节点都可以访问。服务可以有多个服务副本,随时动态扩缩容。
弹性、扩缩容!!服务的高可用!
docker swarm 掌握:搭建集群、启动服务、动态管理容器服务就OK!
概念总结
swarm集群的管理和编号。docker可以初始化一个swarm集群,其他节点可以加入。(管理、工作者)
Node就是一个docker节点。多节点就组成了一个网络集群。
Service任务,可以在管理节点来运行。核心!用户访问!
Task容器内命令,任务
逻辑:
命令-》管理-》api-》调度-》工作节点(创建task容器维护创建)
容器单独没有什么意思,<!--有意义-->-容器编排
Docker Stack
docker-compose 单机部署项目
Docker stack 集群部署
[root@Docker-01 ~]# docker stack --help Usage: docker stack [OPTIONS] COMMAND Manage Docker stacks Options: --orchestrator string Orchestrator to use (swarm|kubernetes|all) Commands: deploy Deploy a new stack or update an existing stack ls List stacks ps List the tasks in the stack rm Remove one or more stacks services List the services in the stack Run 'docker stack COMMAND --help' for more information on a command.
docker-compose up -d wordpress,ymal #单机 docker stack deploy wordpress,ymal #集群 #docker-compose 文件
Docker Secret
安全、配置密码,证书
[root@Docker-01 ~]# docker secret --help Usage: docker secret COMMAND Manage Docker secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets Run 'docker secret COMMAND --help' for more information on a command.
Docker Config
配置
[root@Docker-01 ~]# docker config Usage: docker config COMMAND Manage Docker configs Commands: create Create a config from a file or STDIN inspect Display detailed information on one or more configs ls List configs rm Remove one or more configs Run 'docker config COMMAND --help' for more information on a command.
重点:compose swarm
K8s
云原生时代:云应用 (趋势)
电商网站、在线教育网站...
直接下载=>配置
Docker,Docker Compose,Docker Swarm,Kubernetes(k8s)之间的区别
最近在学习Docker容器,了解到一些相关的技术,像是Kubernetes,Docker-compose,Docker Swarm,分不清这些东西之间的区别,特意去研究了一下,分享一下,适合刚入门学习容器的同学了解。
Dcoker Docker 这个东西所扮演的角色,容易理解,它是一个容器引擎,也就是说实际上我们的容器最终是由Docker创建,运行在Docker中,其他相关的容器技术都是以Docker为基础,它是我们使用其他容器技术的核心。
Docker-Compose Docker-Compose 是用来管理你的容器的,有点像一个容器的管家,想象一下当你的Docker中有成百上千的容器需要启动,如果一个一个的启动那得多费时间。有了Docker-Compose你只需要编写一个文件,在这个文件里面声明好要启动的容器,配置一些参数,执行一下这个文件,Docker就会按照你声明的配置去把所有的容器启动起来,但是Docker-Compose只能管理当前主机上的Docker,也就是说不能去启动其他主机上的Docker容器
*Docker Swarm* Docker Swarm 是一款用来管理多主机上的Docker容器的工具,可以负责帮你启动容器,监控容器状态,如果容器的状态不正常它会帮你重新帮你启动一个新的容器,来提供服务,同时也提供服务之间的负载均衡,而这些东西Docker-Compose 是做不到的
Kubernetes Kubernetes它本身的角色定位是和Docker Swarm 是一样的,也就是说他们负责的工作在容器领域来说是相同的部分,当然也有自己一些不一样的特点。这个就像是Eclipse和IDEA一样,也是一个跨主机的容器管理平台。它是谷歌公司根据自身的多年的运维经验研发的一款容器管理平台。而Docker Swarm则是由Docker 公司研发的。
既然这两个东西是一样的,那就面临选择的问题,应该学习哪一个技术呢?实际上这两年Kubernetes已经成为了很多大公司的默认使用的容器管理技术,而Docker Swarm已经在这场与Kubernetes竞争中已经逐渐失势,如今容器管理领域已经开始已经逐渐被Kubernetes一统天下了。所以建议大家学习的时候,应该多考虑一下这门技术在行业里面是不是有很多人在使用。
需要注意的是,虽然Docker Swarm在与Kubernetes的竞争中败下阵来,但是这个跟Docker这个容器引擎没有太大关系,它还是整个容器领域技术的基石,Kubernetes离开他什么也不是。
总结