docker容器技术(一)

  • 安装docker
  • 环境要求
  • 安装步骤
  • 镜像命令
  • 容器命令
  • 常用其他命令
  • 可视化
  • docker的联合文件系统
  • 容器数据卷
  • Dockerfile
  • 数据卷容器
  • 发布镜像
  • docker网络
  • --link
  • 自定义网络
  • 网络连接
  • 搭建redis集群
  • docker发布springboot项目


安装docker

环境要求

  • 系统内核3.10以上 :
uname -r

#3.10.0-1127.19.1.el7.x86_64
  • centos7以上
cat /etc/os-release

安装步骤

  • 卸载旧版本
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
  • 需要的安装包
sudo yum install -y yum-utils
  • 设置镜像仓库(阿里云)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 更新软件安装包的索引
yum makecache fast
  • 安装
sudo yum install docker-ce docker-ce-cli containerd.io
  • 启动
sudo systemctl start docker
  • 测试shell
docker version 
docker run hello-world
  • 配置阿里云镜像加速器

镜像命令

  • 查看镜像
docker images

docker images --help

docker images -a #显示所有

docker images -q #只显示id
  • 查找镜像
docker search imagename
  • 下载镜像
docker pull mysql #默认下载最新

docker pull mysql:5.7
  • 删除镜像
docker rmi -f imageid

docker rmi -f $(docker images -aq)

容器命令

  • 启动
docker run [可选参数] image

--name Name #设置容器名字

# docker run -d --name nginx01 -p 3344:80 nginx

# -d 后台方式运行

-it #使用交互方式运行,进入容器查看内容

#如:docker run -it centos /bin/bash  exit退出容器

-p #指定容器的端口 -p 8080:8080

-p ip:主机端口:容器端口

-p 主机端口:容器端口

-p 容器端口

-P 随机指定端口

--rm 用完即删,docker ps -a 都看不到
	#docker run -it --rm tomcat:9.0
	#docker run -d --rm -p 8080:8080 tomcat:9.0
-e 环境配置
  • 查看运行
#当前在运行的容器
docker ps 

#历史运行的容器
docker ps -a

#显示指定数量的容器
docker ps -a -n=2
docker ps -n=3

#只显示编号
docker ps -q
  • 进入容器
    方式1:进入当前正在运行的容器
docker exec -it containerid /bin/bash
方式2 :  进入容器后开启一个新的终端。
docker attach containerid #进入容器正在执行的终端,不会启动新的进程!
  • 退出容器
exit #直接容器停止并退出

#ctrl+p+q 不停止容器退出
  • 删除容器
docker rm 容器id  #不能删除运行中的

docker rm -f 容器id

docker rm -f $(docker ps -aq) #强制删除

docker ps -aq |xargs docker rm #通过管道删除
  • 启动和停止容器
docker start 容器id

docker restart 容器id

docker stop 容器id

docker kill 容器id #强制停止容器

常用其他命令

  • 后台启动容器
docker run -d image

问题:docker ps 发现停止了。

常见的坑:容器使用后台启动,就必须有一个前台进程,docker发现没有应用就会自动停止,比如nginx。

解决思路:启动后,创建进程

docker run -d centos /bin/sh -c "while true;do echo hello hi;sleep 1;done" #就不会停止了。
  • 动态查看日志
docker logs -tf containerid

docker logs -tf --tail 10 containerid  #查看历史10条开始
  • 查看镜像的元数据
docker inspect containerid
  • 从容器内拷贝文件到主机上
docker cp containerid:/home/test.java /home #容器可以没有运行中。
  • 查看内存状态
docker stats

可视化

  • portainer(不怎么会用到)
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer #然后直接访问即可
  • rancher(CI/CD)

docker的联合文件系统

  • 分层,分层下载
  • commit镜像
    实战测试:1.启动一个默认的tomcat,2.发现默认的没有webapps引用。3.自己拷贝。4.然后我们commit提交一个镜像,以后我们就使用修改后的镜像。
docker commit -a="zxd" -m="add webapps app" containerId mytomcat01:1.0

容器数据卷

  • -v 挂载(双向同步):主机目录:容器目录
docker run -it -v /home/ceshi:/home centos /bin/bash
#测试:安装mysql
docker run --name mysql01 -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
  • 匿名挂载:在默认路径下创建一串英文作为容器挂载路径
    -v /etc/nginx
  • 具名挂载 :在默认路径下创建指定名字作为容器挂载路径
    -v juming-ng:/etc/nginx
  • 查看:
docker volume ls
  • 查看具体信息
docker volume inspect volume_name
  • 默认挂载卷的位置"Mountpoint": “/var/lib/docker/volumes/volume_name/_data”
  • 扩展:-v /home/ceshi:/home:ro 什么意思
ro:read only 只读 :只能在宿主机中修改

rw:read write 可读可写

Dockerfile

构建docker镜像的构建文件。

  • 快速开始
#编写dockerfile1
vim dockerfile1

  FROM centos                   

  VOLUME ["volume01","volume02"]  //匿名挂载

  CMD echo "-----end-----"      

  CMD /bin/bash 
#构建 -f file -t target
 docker build -f /home/docker_test_volume/dockerfile1 -t zxd/centos:1.0 .
  • 编写Dockerfile
#练习:因为默认的centos没有vim pwd ifconfig命令 我们创建一个image引入这些功能
#dockerfile:

[root@localhost dockerfiles]# cat mydockerfile-centos

FROM centos

MAINTAINER zxd<1726211067@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

#构建:

docker build -f mydockerfile-centos -t zxdcentos:0.1 .
#运行
docker run -it zxdcentos:0.1 

#我们可以用下面查看其它镜像是怎么构建的

docker history [OPTIONS] IMAGE
  • CMD和ENTRYPOINT区别
[root@localhost dockerfiles]# cat dockerfile-cmd

FROM centos

CMD ["ls","-a"]

docker run 243b07ea6534 #可以打印

docker run 243b07ea6534 ls -a #可以打印

docker run 243b07ea6534 -l #报错

FROM centos

ENTRYPOINT ["ls","-a"]

docker run 243b07ea6534 #可以打印

docker run 243b07ea6534 -l #可以打印
  • 制作tomcat的镜像

构建如果是Dockerfile名字不用写 -f

启动

docker容器技术与运维第7章 docker容器技术与高可用实战_云服务

数据卷容器

实现多个容器共享(相互拷贝)

--volumes-from #容器id或者名字

docker run --name centos22 --volumes-from d3e4b745b1d0 -it zxd/centos:1.0

发布镜像

  • 发布镜像到dockerHub


docker容器技术与运维第7章 docker容器技术与高可用实战_云服务_02

如果出问题 push不了


docker容器技术与运维第7章 docker容器技术与高可用实战_云服务_03

  • 发布镜像到阿里云 to容器镜像服务

小结:

docker容器技术与运维第7章 docker容器技术与高可用实战_tomcat_04

docker网络


docker容器技术与运维第7章 docker容器技术与高可用实战_docker_05

有本机回环地址、阿里云内网地址、docker0地址

docker的桥接模式,网卡成对出现veth


docker容器技术与运维第7章 docker容器技术与高可用实战_centos_06

–link

  • Quick start
--link

docker run -d -P --name tomcat01 tomcat

docker run -d -P --name tomcat02 tomcat

docker exec -it tomcat02 ping tomcat01 #ping不成功

ping: tomcat01: Name or service not known

docker run -d -P --name tomcat03 --link tomcat01  tomcat

docker exec -it tomcat03 ping tomcat01 #成功
  • 原理
[zxd997@localhost dockerfiles]$ docker exec -it tomcat03 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.2      tomcat01 dfb824443030

172.17.0.3      fffca5ffb2a2

所以反向是不行的。

不建议使用–link,自定义网络不适用docker0 ,docker0不支持容器名连接访问

自定义网络

  • 查看所有网络
    docker network ls
  • 网络模式:

bridge:桥接模式 docker默认,自己创建也使用bridge模式

none:不配置网络

host:和宿主机共享网络

container:容器网络连通(用的少,局限很大)

  • –net

不写默认是 --net bridge

docker0的特点:默认,域名不能访问,–link可以打通连接

#我们可以自定义一个网络

docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

#然后启动两个tomcat,使用刚刚创建的网络

docker run -d -P --name tomcat11 --net mynet tomcat

docker run -d -P --name tomcat22 --net mynet tomcat

docker network inspect mynet #会看到container多了两个网络

#好处:不用--link,也能ping name了

网络连接

连通不同网络下的容器

docker run -d -P --name tomcat4 tomcat

docker exec -it tomcat4 ping tomcat11

ping: tomcat11: Name or service not known #ping不通

docker network connect mynet tomcat4 #就是把mynet网络加了tomcat4,

docker exec -it tomcat4 ping tomcat11 #成功

#所以tomcat4就能ping通mynet下的容器了

搭建redis集群

分片+高可用+负载均衡

#创建redis集群网络

docker network create --subnet 192.169.0.0/16 redis

#shell创建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-config-file nodes.conf

cluster-node-timeout 5000

cluster-announce-ip 192.169.0.1${port}

cluster-announce-port 6379

cluster-announce-bus-port 16379

appendonly yes

EOF

done

#shell 启动6个redis

for port in $(seq 1 6); \

do \

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 192.169.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

done

#创建集群

 redis-cli --cluster create 192.169.0.11:6379 192.169.0.12:6379 192.169.0.13:6379 192.169.0.14:6379 192.169.0.15:6379 192.169.0.16:6379 --cluster-replicas 1

#打印信息默认分配3master3slave

Master[0] -> Slots 0 - 5460

Master[1] -> Slots 5461 - 10922

Master[2] -> Slots 10923 - 16383

Adding replica 192.169.0.15:6379 to 192.169.0.11:6379

Adding replica 192.169.0.16:6379 to 192.169.0.12:6379

Adding replica 192.169.0.14:6379 to 192.169.0.13:6379

M: 7f4666840dd557177d0b9a2e38f37980e2399aae 192.169.0.11:6379

   slots:[0-5460] (5461 slots) master

M: 5a6bafeef212cab67598403a006cb12e033ed2a3 192.169.0.12:6379

   slots:[5461-10922] (5462 slots) master

M: bfeb82d5509cba9576942dafda595a56e2e247b8 192.169.0.13:6379

   slots:[10923-16383] (5461 slots) master

S: 4323af513da7a72974ef948b25fc4093054b460f 192.169.0.14:6379

   replicates bfeb82d5509cba9576942dafda595a56e2e247b8

S: a57402b9a5f7de01a85b47d85fe540efbaa277c7 192.169.0.15:6379

   replicates 7f4666840dd557177d0b9a2e38f37980e2399aae

S: 7c25854b274173ef77847143250ba12d76918f40 192.169.0.16:6379

   replicates 5a6bafeef212cab67598403a006cb12e033ed2a3

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 192.169.0.11:6379)

M: 7f4666840dd557177d0b9a2e38f37980e2399aae 192.169.0.11:6379

   slots:[0-5460] (5461 slots) master

   1 additional replica(s)

M: bfeb82d5509cba9576942dafda595a56e2e247b8 192.169.0.13:6379

   slots:[10923-16383] (5461 slots) master

   1 additional replica(s)

S: 4323af513da7a72974ef948b25fc4093054b460f 192.169.0.14:6379

   slots: (0 slots) slave

   replicates bfeb82d5509cba9576942dafda595a56e2e247b8

S: a57402b9a5f7de01a85b47d85fe540efbaa277c7 192.169.0.15:6379

   slots: (0 slots) slave

   replicates 7f4666840dd557177d0b9a2e38f37980e2399aae

M: 5a6bafeef212cab67598403a006cb12e033ed2a3 192.169.0.12:6379

   slots:[5461-10922] (5462 slots) master

   1 additional replica(s)

S: 7c25854b274173ef77847143250ba12d76918f40 192.169.0.16:6379

   slots: (0 slots) slave

   replicates 5a6bafeef212cab67598403a006cb12e033ed2a3

#进入某个redis

docker exec -it redis-1 /bin/sh

#登入到集群

redis-cli -c

#查看信息

cluster info

#查看nodes

cluster nodes

#测试:

set myname zxd 

#然后get myname 失败,重启

/data # redis-cli -c

127.0.0.1:6379> get myname

-> Redirected to slot [12807] located at 192.169.0.14:6379

#"zxd" 从机4获取到

#再查看

192.169.0.14:6379> cluster nodes

7f4666840dd557177d0b9a2e38f37980e2399aae 192.169.0.11:6379@16379 master - 0 1599807281431 1 connected 0-5460

5a6bafeef212cab67598403a006cb12e033ed2a3 192.169.0.12:6379@16379 master - 0 1599807281532 2 connected 5461-10922

a57402b9a5f7de01a85b47d85fe540efbaa277c7 192.169.0.15:6379@16379 slave 7f4666840dd557177d0b9a2e38f37980e2399aae 0 1599807281000 5 connected

bfeb82d5509cba9576942dafda595a56e2e247b8 192.169.0.13:6379@16379 master,fail - 1599807044291 1599807042568 3 connected

7c25854b274173ef77847143250ba12d76918f40 192.169.0.16:6379@16379 slave 5a6bafeef212cab67598403a006cb12e033ed2a3 0 1599807281935 6 connected

4323af513da7a72974ef948b25fc4093054b460f 192.169.0.14:6379@16379 myself,master - 0 1599807280000 8 connected 10923-16383

#3fail 4变成了master

docker发布springboot项目

#编写Dockerfile

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

#然后将package的jar和Dockerfile拷贝到linux中,

#构建: 
docker build -t springboot-test01 .

#运行:
docker run -p 8083:8080 --name springboot-test-app01 springboot-test01

#访问http://192.168.66.100:8083/ppq ok

#问题:只有linux可以访问,外网主机都不行?没有读取到application.xml的端口,而是默认启用了8080