fundamentals\java\docker 读书笔记

原文链接:++Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers++

docker

“如果你们在使用微服务,而没有使用docker或者云,那么你就是在浪费你的钱”(是个土豪)

安装

下载离线安装包下载地址

tar -xvf docker-18.06.1-ce.tgz
# 注意 docker 一定要直接放在 bin 下,以下的方式无法注册成系统服务
# cp docker /usr/local/common/
cp docker/* /usr/bin/
# 注册成系统服务
vim /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
# 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
chmod +x /etc/systemd/system/docker.service

systemctl daemon-reload
systemctl start docker			#启动Docker
systemctl enable docker.service		#设置开机自启
systemctl status docker		#查看Docker状态
docker -v			#查看Docker版本

或者你懂的

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

启动 Docker 之后的内存(空跑)
dockerMemory

docker 基本指令

docker run
# 启动容器,无则下载
docker run nginx
# 列出容器
docker ps
# 列出容器,包括已经停止的容器 all
docker ps -a
# 停止名字为 silly_sammet 的容器
docker stop silly_sammet
# 永久移除容器
docker rm silly_sammet
# 查看所有镜像
docker images
# 永久移除镜像,确保没有被运行中的容器使用
docker rmi nginx
# 仅下载镜像
docker pull nginx
# 容器仅仅在任务执行过程中存在,一旦容器内的应用进程停止,容器将自动停止
# 在停止前睡眠 5 秒
docker run ubuntu sleep 5
# 对容器中的程序执行命令
docker exec 容器名称 cat /etc/hosts
# 使用 -d 后台运行容器
docker run -d kodekloud/simple-webapp
# 使用 attach 容器ID(自动补全) 查看容器日志
docker attach a043d

Dokcer Labs 网站可以免费学习Docker的指令

docker run 详细配置
# 指定版本 :TAG
docker run redis:4.0
# 使用 -i 输入 input
docker -i run kodekloud/simple-prompt-docker
# 使用 -it 可以绑定到 terminal
docker -it run kodekloud/simple-prompt-docker
# 端口映射
docker -p 80:5000 run kodekloud/webapp
docker -p 8000:5000 run kodekloud/webapp
docker -p 8001:5000 run kodekloud/webapp
# docker 拥有自己独立的文件系统,移除容器后随容器一起销毁
# 容积映射 volume
docker run -v /opt/datadir:/var/lib/mysql mysql
# 查看容器详细信息
docker inspect blissful_hopper
# 查看容器日志 container logs
docker logs blissful_hopper
环境变量
# 设置环境变量 ENV Variables
docker run -e APP_COLOR=blue simple-webapp-color
docker run -e APP_COLOR=green simple-webapp-color
docker run -e APP_COLOR=pink simple-webapp-color
# 查看已经设置的环境变量
docker inspect blissful_hopper

镜像

怎样创建自己的镜像

Dokderfile = INSTRUCTION + ARGUMENT

# 以基础镜像或者操作系统开始
FROM Ubuntu

# 安装所有的依赖
RUN apt-get update
RUN apt-get install python

RUN pip install flask
RUN pip install flask-mysql

# 拷贝源码到镜像中
COPY . /opt/source-code

# 指定入口点,当 Docker 容器启动时将被调用
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
# 当程序被 build 时,dockerFile 将逐行层层演进式安装
docker build Dockerfile -t mmumshad/my-custom-app
# 使用 history 指令可以查看 docker 的 build 情况
docker history mmumshad/simple-webapp
# 每一步的 build 都将被缓存
docker build Dockerfile -t mmumshad/my-custom-app

发布

# mmumshad = 账户名, my-custom-app = 镜像名
docker push mmumshad/my-custom-app

CMD 和 EntryPoint

docker 容器中可以部署 web服务、应用服务器、数据库、计算或者分析任务。

CMD 模式下,通过 run [COMMAND] 将重写参数
ENTRYPOINT 模式下 run [ARGS] 将追加参数

CMD 语法结构
# CMD 的结构
CMD command param1		CMD sleep 5
CMD ["command", "param1"]	CMD ["sleep", "5"]

Nginx 的 Dockerfile

# Install Nginx
RUN \
  add-apt-repository -y ppa:nginx/stable && \
  apt-get update && \
  apt-get install -y nginx && \
  rm -rf /var/lib/apt/lists/* && \
  echo "\ndaemon off;" >> /ect/nginx/nginx.conf && \
  chown -R www-data:www-data /var/lib/nginx

# Define mountable directories. 定义持久目录
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf"]

# Define working directory.
WORKDIR /etc/nginx

# Define default command.
CMD ["nginx"]
# CMD 定义的指令将在容器启动时被执行。
CMD ["nginx"]

MySQL 的 Dockerfile

ARG MYSQL_SERVER_PACKAGE_URL=https://repo.mysql.com/yum/mysql-8.0-community/docker/x86_64....
ARG MYSQL_SHELL_PACKAGE_URL=http://repo.mysql.com/yum/mysql-tools-community/el/7/x86_74...

# Install server
RUN rpmkeys --import https://repo.mysql.com/RPM-GPG-KEY-mysql \
  && yum install -y $MYSQL_SERVER_PACKAGE_URL $MYSQL_SHELL_PACKAGE_URL \
  && yum clean all \
  && mkdir /docker-enterpoint-initdb.d

VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /entrypoint.sh
COPY healthcheck.sh /healthcheck.sh
ENTRYPOINT ["\entrypoint.sh"]
HEALTHCHECK CMD /healthcheck.sh
EXPOSE 3306 33060
CMD ["mysqld"]

再栗如 Ubuntu 的 Dockerfile

# Pull base image.
FROM ubuntu:14:04

# Install.
RUN \
  sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get -y upgrade && \
  apt-get install -y build-essential && \
  apt-get install -y software-properties-common && \
  apt-get install -y byobu curl git htop man unzip vim wget && \
  rm -rf /var/lib/apt/lists/*

# Add files.
ADD root/.bashrc /root/.bashrc
ADD root/.gitconfig /root/.gitconfig
ADD root/.scripts /root/.scripts

# Set environment variables.
ENV HOME /root

# Define working direcotry.
WORKDIR /root

# Define default command.
CMD ["bash"]

通过 run 命令将重写 CMD

# 往默认的 Dockerfile 中重写 CMD
docker run ubuntu [COMMAND]
docker run ubuntu sleep 5

创建基于 Ubuntu 的镜像 永久重设 CMD

FROM Ubuntu

CMD sleep 5
# 编译新得镜像
docker build -t ubuntu-sleeper
docker run ubuntu-sleeper
通过 EnterPoint 实现传参

ubuntu-sleeper

FROM Ubuntu

# EntryPoint 也能指定 Main 程序的入口
# EntryPoint 能接收命令行传入的参数,并追加到命令之后
ENTRYPOINT ["sleep"]

# ENTRYPOINT 和 CMD 相结合
# 如果执行 docker run ubuntu-sleeper 则使用默认值 sleep 5
# 如果执行 docker run ubuntu-sleeper 10 则 CMD["5"] 被 10 覆盖
CMD ["5"]
# 使用ENTRYPOINT,以下命令将等价于 CMD sleep 10
docker run ubuntu-sleeper 10
# 动态执行 EntryPoint
docker run --enterypoint sleep 2.0 ubuntu-sleeper 10

Docker 网络

# 使用默认的 Bridge 网络
docker run ubuntu
# 不使用网络
docker run ubuntu --network=none
# 使用主机网络
docker run ubuntu --network=host
Bridge

Bridge 网络是默认配置。由 Docker 在主机上创建的内部网络(有点类似于 AMQ 的桥接?)
每个容器获得一个内部的IP(通常是172.17.0.x网段,docker0为主机),Docker 通过内部IP和容器通信

Host

Host 网络下,容器直接使用主机的网络,而不需要任何的端口映射
这样,因为IP和端口不能重复,你将不能同时启动多个一样的容器(端口冲突)

None

None 网络下,容器未连接到任何网络,并且无法访问外部网络或其他容器。它们运行在一个独立的网络中。

自定义网络

假如我们希望使用容器1之和容器4通信,容器2和容器3通信?

# 自定义一个额外的 bridge 网络
# 容器1,容器4 使用默认的 172 网段的 bridge 网络 
# 容器2,容器3 使用自定义的 182 网段的网络 
# 达到分离应用的目的
docker network create \
  -- driver bridge \
  -- subnet 182.18.0.0/16
  custom-isolated-network

# 使用 ls 查看所有网络
docker network ls
# 使用 inspect 查看某个容器的网络配置 IPAddress,MacAddress,Gateway
docker inspect blissful_hopper

我们可以通过容器ID、容器名称或者是IP地址来访问其他容器。为了防止系统重启后,容器的内部IP地址发生改变,docker 容器中内置了 DNS 解析。
Docker 使用网络名称空间为每个容器创建一个单独的名称空间,然后使用虚拟以太网对将容器连接在一起

Docker 存储

# docker的默认存储位置 位于 /var/lib/docker
docker info | grep "Docker Root Dir"
# aufs
# containers 容器相关文件
# image 镜像相关文件
# volumes 容积相关文件

Docker 的“层”级存储结构

  • docker文件中的每一行指令在docker中创建一个新层。
  • 每一层针对上一层增量存储
  • 多个容器重用已经编译好的“层”
    栗如

第一层是一个基本的Ubuntu操作系统

FROM Ubuntu

第二层,安装了所有apt包

> RUN apt-get update
> RUN apt-get install python

第三层是Python包

> RUN pip install flask
> RUN pip install flask-mysql

第四层是复制源代码

> COPY . /opt/source-code

第五层配置镜像程序的入口

> ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run
前五层是只读的 称为 镜像层

第六层 容器层 当你执行 docker run 命令时,将会新建一个可读写的“容器层”
容器层用于存储容器创建的数据,栗如:应用日志、容器临时文件、容器中的所有被修改的文件(COPY-ON-WRITE)
容器层和容器共存亡

持久化容器层数据

可以创建 持久化 volume

# docker volume create 将在 docker 文件夹下创建名为 volumes/data_volume 的文件夹
docker volume create data_volume
# 使用 data_volume 数据不会随着容器而销毁
docker run -v data_volume:/var/lib/mysql mysql
# 如果 data_volume2 不存在,docker 将自动新建 data_volume2 并挂载到容器上
docker run -v data_volume2:/var/lib/mysql mysql
# 在其他文件夹 绑定挂载
docker run -v /data/msyql:/var/lib/mysql mysql
# \ 参数模式
docker run \
  --mount type=bind,source=/data/mysql,target=/var/lib/mysql mysql
存储驱动

Docker 将依据操作系统自动选择合适的驱动,不同的驱动性能不一样,自行参考文档

ubuntu 默认 AUFS
ZFS
BTRFS
Device Mapper
Overlay
CentOs 默认 Overlay2

Docker 组合指令

# 启动 传统方式simple-webapp
docker run mmumshad/simple-webapp
docker run mongodb
docker run redis:alpine
docker run ansible

使用组合指令 Docker compose
docker-compose.yml

services:
	web:
		image: "mmumshad/simple-webapp"
	database:
		image: "mongodb"
	messaging:
		image: "redis:alpine"
	orchestration:
		image: "ansible"
# 使用组合指令 docker compose 启动 simple-webapp
docker-compose up

栗二:

# -d 后台启动,--name 为容器取名
docker run -d --name=redis redis
#
docker run -d --name=db postgres:9.4 --link db:db
# voting-app 依赖于 redis, redis 主机(host)将指向 名为redis 的容器
docker run -d --name=vote -p 5000:80 --link redis:redis voting-app
docker run -d --name=result -p 5001:80 result-app
docker run -d --name=worker --link db:db --link redis:redis worker
# 将这些容器连接起来 link
docker

使用组合指令 Docker compose
docker-compose.yml

redis:
	image: redis
db:
	image: postgres:9.4
vote:
	# image: voting-app
	build: ./vote
	ports:
	-5000:80
	links:
	-redis
result:
	image: result-app
	ports:
	-5001:80
	links:
	-db
worker:
	image: worker
	links:
	-redis
	-db
docker-compose up
Docker compose file versions
redis:
	image: redis
db:
	image: postgres:9.4
vote:
	image: voting-app
	ports:
	- 5000:80
	links:
	- redis

第一版的问题:

  • 只能使用 Bridge 桥接网络
  • 无法指定容器间的依赖关系或者启动顺序

版本2中,所有的容器都连接到一个新建的专用桥接网络,没必要写links,也可以使用 dependsOn 指定启动顺序和依赖关系

version: 2
services:
	redis:
		image: redis
	db:
		image: postgres:9.4
	vote:
		image: voting-app
		ports:
		- 5000:80
		depends_on:
		-redis

版本3支持 Docker Swamp等,参见 Docker Stacks

version: 3
services:
	redis:
		image: redis
	db:
		image: postgres:9.4
	vote:
		image: voting-app
		ports:
		- 5000:80
		links:
		- redis
Docker Compose Network

user —front-end network—> app — back-end network —> backend

version: 2
services:
	redis:
		image: redis
		networks:
		- back-end
	db:
		image: postgres:9.4
		networks:
		-back-end
	vote:
		image: voting-app
		networks:
		- front-end
		- back-end
	result:
		image: result
		networks:
		- front-end
		- back-end
network:
	front-end:
	back-end:

Docker 搭建私服

Docker Swarm

kubernetes

当我有上千个节点时,我需要自己实现负载均衡和逐个启动/重启/管理这些实例

# 使用 Docker CLI 可以运行一个应用程序实例
docker run my-web-server
# 使用 kubernetes CLS(cube)一个命令可以运行上千个实例
kubectl run --replicas=1000 my-web-server
# 可以根据系统负载新增实例到 2000 个
kubectl scal --replicas=2000 my-web-server
# 使用1个指令同时更新这 2000 个实例上的应用程序为 2 版本
kubectl rolling-update my-web-server --image=web-server:2
# 如果更新后出现问题,还支持回滚
kubectl rolling-update my-web-server --rollback

kubernetes 在 Authorization Network Storage 上有广泛的支持,主流的云服务都提供了对 kubernetes 的原生支持。
kubernetes 使用 Docker 以 docker 容器的形式托管应用程序。kubernetes支持 Docker 之外的技术,栗如 rocket 或 cryo。

kubernetes

kubernetes 包含一个主节点(Master)和多个节点(Node)的集群方式(Master-Slave)。由 API Server、etcd、kubelet、Container Runtime、Controller、Scheduler组成

kubectl run hello-minikube
kubectl cluster-info
kubectl get nodes
kubectl run my-web-app --image=my-web-app --replicas=100
发布了26 篇原创文章 · 获赞 4 · 访问量 2534

猜你喜欢

转载自blog.csdn.net/u012296499/article/details/104262494