Spring Cloud Kubernetes入门必知运维知识之Docker

原创 吴就业 143 0 2020-01-04

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://wujiuye.com/article/ea389501b7684a40be1547c2b7f997e1

作者:吴就业
链接:https://wujiuye.com/article/ea389501b7684a40be1547c2b7f997e1
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

本篇文章写于2020年01月04日,从公众号|掘金|CSDN手工同步过来(博客搬家),本篇为原创文章。

docker容器化部署应用可以简化应用的部署流程。

假设部署一个应用需要在机器上安装和配置nginxtomcat,如果需要新增一台服务器,或者切换服务器,那么就要重复同样的操作,安装nginxtomcat并配置。容器化部署就是一次配置到处使用,将安装nginx配置nginx这一系列工作制作成一个镜像,在服务器上通过docker拉取镜像并启动容器即可,基于此实现集群自动伸缩。

图片

docker入门简单,用好难,特别是制作镜像。随便做一个镜像就是1g大小,这该怎么用。如果每次部署都要拉1g的镜像,那么部署就要等待非常长的时间。如果在Dockerfile中使用yum安装一些软件,build的时间会很长,加上镜像太大,传输也耗时。应尽量使用安装包安装替换yum安装,以及使用尽量小的基础镜像。

使用Dockerfile构建镜像,我们可以理解为,docker基于Dockerfile中的FROM基础镜像,启动了一个容器,然后在容器中执行Dockerfile中定义的脚本,执行完成后再打包成镜像。

docker的镜像是分层的,你可以先定制一个基础镜像,再通过基础镜像去实现差异化定制。

比如部署一个java项目,每台机器都需要jdk,但并不是每台机器都需要安装nginx,那么就可以先制作一个jdk基础镜像。当然,制作jdk基础镜像也是基于更底层的基础镜像,比如centos。然后再基于jdk基础镜像制作nginx镜像,再制作应用镜像。制作应用镜像如果需要用到nginx就可以基于nginx镜像,不需要依赖nginx的就可以直接基于jdk镜像。

docker的命令不需要记,动动手去试一试就记住了,记不住可以使用docker -help查看命令。新版本docker将命令规范了,如docker image是镜像相关的,docker container是容器相关的,同样,也可以使用docker container -help来查看命令帮助。

Docker的端口、网络与容器卷

学习doker除了镜像制作之外,还需要理解这三点:端口映射、网络模式、容器卷(volume)。

端口映射

将宿主机端口映射到容器的端口,外部通过访问宿主机端口从而访问容器内应用。

如容器中redis使用的端口是6379,可以将宿主机的10880端口与容器的6379端口映射,外部通过宿主机ip10880端口访问容器中的redis

### 使用镜像运行容器
### -p 10880:6379 将宿主机10880端口映射到容器6379端口
[root@wujiuye01 redis-app]# docker container run -itd --name simple-redis \
                 -p 10880:6379 wujiuye/simple-redis:5.0.7
05676da445839b1f4a1995148b4656d029721503a16d67edad37956fe7ea9f3a

### 宿主机访问容器中的redis
[root@wujiuye01 redis-app]# /root/redis/redis-5.0.5/src/redis-cli -p 10880
127.0.0.1:10880>

网络模式

docker支持5种网络模式,这里不做详细分析。

在启动容器时,可以指定使用哪种网络模式:docker container run --network [网络模式]

容器卷(volume)

应用部署在一台服务器上运行会产生日记,不能随着容器的删除而导致日记被删除,所以需要将容器中的工作目录与宿主机的目录映射。或者说mysql容器,容器移除而数据库文件不能删除。

docker为我们提供了三种不同的方式将容器卷或宿主机目录从宿主机挂载到容器中:volumebind mounttmpfs

volumes

docker管理宿主文件系统的一部分(/var/lib/docker/volumes/容器id)

docker container run命令指定的--mount src=test-vol,dst=/data/apps/test是将容器卷挂载到容器的/data/apps/test目录。将文件放到容器的/data/apps/test目录下,可以在宿主机的/var/lib/docker/volumes/test-vol目录看到,反过来也是一样的。如果不指定--mount,默认也是使用volumes,并且容器卷的名称就是容器id,也是在 /var/lib/docker/volume/目录下。

### 创建容器卷
[root@wujiuye01 docker]# docker volume create test-vol
test-vol
### 查看容器卷信息
[root@wujiuye01 docker]# docker volume inspect test-vol
[
    {
        "CreatedAt": "2020-01-04T17:57:08+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
        "Name": "test-vol",
        "Options": {},
        "Scope": "local"
    }
]
### 将容器卷挂载到容器
[root@wujiuye01 docker]# docker container run -itd --name test \
        --mount src=test-vol,dst=/data/apps/test wujiuye/test:1.0.0

bind mounts

可以存储在宿主机系统的任意目录,宿主机的目录必须存在。

如果宿主机新增磁盘是挂载在/data目录的,建议使用这种,如使用awsec2实例。

docker container run -itd --name test \
  --mount type=bind,src=宿主机目录,dst=容器目录 wujiuye/test:1.0.0

将指定的宿主机目录挂载到容器的指定目录:将文件放到<容器指定目录>下,可以在<宿主机指定目录>看到,反过来也是一样的。

tmpfs

挂载存储在宿主机系统的内存中,不会写入宿主机的文件系统。

Docker的安装与启动

docker安装

# 较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序,请卸载它们以及相关的依赖项。
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 安装所需的软件包。yum-utils 提供了 yum-config-manager ,并且 device mapper 存储驱动程序需要 device-mapper-persistent-data 和 lvm2
sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

# 设置稳定的仓库。
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# 安装最新版本的 Docker Engine-Community 和 containerd
sudo yum install docker-ce docker-ce-cli containerd.io

docker服务启动与停止

## 停止
sudo systemctl stop docker
## 启动
sudo systemctl start docker

Docker使用简单事例

制作一个简单的redis镜像

准备redis安装包和配置文件,新建一个Dockerfile文件,目录结构如下:

-rw-r--r-- 1 root root     583 Jan  4 18:56 Dockerfile
-rw-r--r-- 1 root root 1984203 Jan  4 18:52 redis-5.0.7.tar.gz
-rw-r--r-- 1 root root   61797 Jan  4 18:52 redis.conf

编写Dockerfile文件,基于centos:7镜像:

FROM centos:7
MAINTAINER wujiuye <[email protected]>

# 使用ps 命令 :ps -ef|grep redis
RUN yum install -y procps

# redis安装包和配置文件
ADD redis-5.0.7.tar.gz /usr/local/redis/
COPY redis.conf /usr/local/redis/local-redis.conf

# 安装gcc
RUN yum install gcc -y
# 安装make
RUN yum install make -y

# 编译redis
RUN cd /usr/local/redis/redis-5.0.7 && \
    make

RUN yum clean all

EXPOSE 6379

# 启动redis
ENTRYPOINT /usr/local/redis/redis-5.0.7/src/redis-server
CMD ["/usr/local/redis/local-redis.conf"]

构建镜像

### 目录下的文件
[root@wujiuye01 redis-app]# ls
Dockerfile  redis-5.0.7.tar.gz  redis.conf

### 构建镜像
[root@wujiuye01 redis-app]# docker image build --tag wujiuye/simple-redis:5.0.7 .
....
Successfully built 2aab79854763
Successfully tagged wujiuye/simple-redis:5.0.7

--tag打标签,最后的‘.’Dockerfile文件所在的位置。

根据镜像启动容器

docker container run \
--rm -itd \
--ulimit nofile=102400:102400 \
--name=simple-redis \
-p 10880:6379 \  # 可写多个
--mount type=bind,src=/data/redis-app/,dst=/usr/local/redis \
wujiuye/simple-redis:5.0.7

查看容器信息

使用docker container ls命令列出所有容器。

[root@wujiuye01 redis-app]# docker container ls
### 容器id  使用的镜像 容器执行的命令 创建时间   容器状态  端口信息  容器名称
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                     NAMES
05676da44583        wujiuye/simple-redis:5.0.7   "/bin/sh -c /usr/loc…"   6 minutes ago       Up 6 minutes        0.0.0.0:10880->6379/tcp   simple-redis

将镜像push到docker hub

图片

在测试完镜像可用之后,可以选择push到远程仓库,也可自己搭建一个镜像仓库。

[root@wujiuye01 redis-app]# docker push wujiuye/simple-redis:5.0.7
The push refers to repository [docker.io/wujiuye/simple-redis]
dafbadcc43aa: Pushing [==>                                                ]  1.281MB/23.62MB
879a0e8874ba: Pushing [=============================>                     ]  66.96MB/111.8MB
ccc522a455bc: Pushing [>                                                  ]  549.9kB/100.2MB
879a0e8874ba: Pushing [================================>                  ]  73.04MB/111.8MB
ccc522a455bc: Pushing [>                                                  ]  1.107MB/100.2MB
ff7b8add839d: Pushing [=================>                                 ]  51.75MB/146.8MB
dca066a10cae: Pushing [>                                                  ]  557.1kB/100.8MB
77b174a6a187: Waiting

Other

容器停止

1)、docker kill [容器名]
可选参数:
--signal: 发送信号量

2)、docker stop []

删除容器和镜像

删除某个镜像:

1)、docker image rm [repository,如:wujiuye/simple-redis:5.0.7]
2)、docker image rm [镜像id]

删除某个容器:

docker container rm [容器名称 或 容器id]
#后端

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

JVM垃圾回收GC Root与安全点Safepoint

我看很多资料在介绍`GC Root`时,并没有说栈帧的操作数栈上引用的对象也是`GC Root`,包括我去翻阅《深入理解Java虚拟机》这本书也是一样。所以我才好奇。

服务提供者假死,记一次full gc问题排查

线上某服务一直运行很稳定,最近突然就`cpu`百分百,`rpc`远程调用全部失败,并走了`mock`逻辑。重启后,一个小时后问题又重现。于是`dump`线程栈信息,但不仔细看也看不出什么问题。于是就有了一番排查历程。

JITWatch查看字节码被JIT编译后的汇编代码

最近看书看到关于`volitale`关键字与`jmm`内存模型的介绍,这个知识点似乎看了好多次,背都能背下来了。但理论性的东西真的很容易忘记,看不到摸不着。于是乎,我上网搜索看底层机器指令的实现,发现不少文章说可以看到`java`编译后的汇编代码,于是了解到`jitwatch`这个工具,从名字上也能看出`jit`编译器监视的意思。

Dubbo源码,详解dubbo协议数据包及解包过程

Dubbo框架的传输层默认使用dubbo协议,这也是一种RPC远程通信协议。学习Dubbo,我们有必要了解dubbo协议长什么样,最好的办法就是从源码中寻找答案。

Netty源码-详解Http协议的数据包解码过程

今天我们来分析下`netty`是如何解析`http`协议数据包的。重点是分析`HttpObjectDecoder`类的`decode`方法的源码,`http`协议数据包的解码操作都是在该方法中完成的。

反向理解ThreadLocal,或许这样更容易理解

已经有那么多作者写ThreadLocal的源码分析,我还是想写下这篇,换个思路去分析。