2020/05/01 K8S原理介绍2
Docker容器的高级操作
高级操作总的来讲有4个点,
1映射端口
2挂载数据卷
3传递环境变量
4容器内安装软件
生产中不得不会
做端口映射就是对外提供服务,需要先下载一个nginx镜像
下载一个镜像。1.12.2版本的nginx
打一下标签 docker tag image id 标签名
docker run -p 容器外端口:容器内端口
现在宿主机上81监听了
映射端口用-p来映射, 宿主机端口:容器内端口
需要容器里的某一个目录和宿主机的没目录关联起来
创建个目录,然后里面把百度首页wget下来
nginx先跑着
把宿主机的/root/html挂载到nginx容器里的/usr/shar/nginx/html
现在有两个容器
进到82这个容器里看一下
实际上这个目录是和宿主机目录里关联起来了,容器的mount是看不到的
退出容 器
这时候其实可以用inspect看一下
inspect可以看到挂载目录,inspect可以看到容器里的细节
docker之所以比虚拟机普及的快,早些年虚拟化火的时候也有编排工具,openstack,xen,exsi,这些比docker差,也不是迁移的问题,容器可以通过传递变量的方式,按照你想要的方式启动,容器并不是信息孤岛,而虚拟机的都是 孤岛。容器之所以可以称霸云计算,最重要的就是云原生,可以给容器定义环境变量,让容器按照预期的跑起来
-e参数就可以传递环境变量
docker run -e 环境变量key:(等于号和冒号都可以)环境变量value
这个是打印当前容器环境变量的所有值
不加-e就没有
给容器配置环境变量,要么k8s kubectl要么-e
可以连续设置多个值
容器如果是红帽系的发行版就是yum,ubuntu或者debian系的就用apt-get,alpine就是apt
现在要给nginx安装给一个软件
先把这个apt源更新了
先把这个apt源更新了,然后安装curl
现在就有curl命令了
现在需要把临时安装的固化住,docker commit -p pause containerid 给一个新的标签 nginx:curl
这样就推到公网上去了
从docker hub里找到nginx,作为mount,这样就不消耗网络流量
这些层都是mounted掉的,都是从library/nginx上mount来的
这里的标签只有一个 curl,以后用就可以docker pull docker.io/oldboy1103/nginx:curl
这里有docker 高级应用 4个必须会
Dockerfile概述
容器4个高级操作必须会。
映射端口 -p
挂载数据卷 -v
环境变量 -e
容器安装软件。(老外生产上一般容器起来用debian系,不用红帽系)
容器的生命周期:
1.检查本地是否存在镜像,(容器是基于镜像实例化出来的,也是借鉴了面向对象的编程方法),如果不存在就从远端仓库检索
2.利用镜像启动容器,依照镜像模版把容器启动起来并在容器最上一层附加读写层,直到容器被删除,读写层就彻底没了
3.分配一个文件系统,并在只读的镜像层外挂在一层读写层
4.从宿主机配置的网桥接口中桥接一个虚拟接口到容器
5.从地址池配置一个ip给容器,我们配置的是172.7.5.0/24 253个可用ip,172.7.5.1在docker0这个设备上,本机就把docker0作为一个网络设备
6.执行用户指定命令,就看容器有没有
7.执行完毕后容器终止,指定的命令不能在前台一直运行,就会运行完就退出
data/docker里有很多镜像,容器还在本地docker引擎存储,没有rm掉,还能启动,所以可写层还在,因为container id都没变
容器最希望的就是长期running
先简单入个门,学习4个指令,dockerfile的指令特别多。容器可以通过commit命令,提交成一个镜像,其他制作镜像方法就是dockerfile
dockerfile是构建docker镜像的源码。
docker可以自动的构建镜像,docker引擎可以从dockerfile里读取instructions指令自动构建镜像。
dockerfile是一个文本文件,包含了所有命令去和用户的命令去组装镜像,dockerfile就是组装镜像的清单。
用docker build这个命令根据dockerfile,自动构建镜像
dockerfile是根据指令来编排镜像了
可以通容器提交commit去构建镜像,可以通过dockerfile去build一个镜像,生产中90%都是用build
dockerfile的格式
#注释
指令(大写),内容(消息)
尽管指令是大小写不敏感,但是,我们强烈建议指令用大写,内容用小写
docker是按照顺序执行dockerfile的指令,从上到下
每一个dockerfile的第一个非注释行指令,必须是FROM,指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境
实践中,基准镜像可以是任何可用镜像文件,默认,docker build会在docker本地上找指定的镜像文件,本地不存在时,则会从docker registry远端拉取需要的镜像文件
Dockerfile1
user指的是,init,pid=1的进程,是什么用户跑的
user是指定nginx:v1.12.2的用户用到的是nginx。
workdir的意思是,wordir以下的环境指令切到了/usr/shar/nginx/html下,指定一个workdir,就相当于cd到了这个目录
workdir工作目录的,这个并不是你的构建工作目录,而是给build,copy和add设定工作目录的
当某些命令执行之前先cd到目录中去,这个目录应该构建下的子目录
做下示范
第一个非注释指令必须是FROM
workdir工作目录的,这个并不是你的构建工作目录,而是给build,copy和add设定工作目录的
当某些命令执行之前先cd到目录中去,这个目录应该构建下的子目录
docker build 构建一个镜像,.点号代表本目录的dockerfile。-t tag
进入交互式
workdir工作目录的,这个并不是你的构建工作目录,而是给build,copy和add设定工作目录的
当某些命令执行之前先cd到目录中去,这个目录应该构建下的子目录
Dockerfile2
user是定义docker里的进程,使用哪个用户来启动
workdir,相当于cd进去,指定exec进去,run这个容器的,默认就是workdir到这里去
ADD和COPY类似,建议用ADD,因为ADD范围更加广,可以接受tar包和url,expose指令就是定义容器哪个端口要被暴露出来
把index.html,放到docker容器里/usr/share/nginx/html/index.html,之前的-v挂载数据卷,把宿主机的系统和docker挂载起来。没有把html固化到容器里。
add 可以把本地文件固化到镜像里
退出之前的容器
把exited状态的都删除掉
把之前的html拷贝到当前目录下
add 把当前目录下的index.html放到容器里的/usr/share/nginx/index.html
构建镜像
现在要run起来,-大P
不指定workdir的时候,就是文件系统的/根
容器里需要启动下nginx
在另外终端宿主机上看看,32768是随机生成的端口
如果不用交互式启动nginx,可以用命令行 -d,把之前的bin/bash删除,现在端口是36769
ADD指令是往镜像里放东西必备指令。-P大P只能随机端口,-p小p可以指定端口,所以生产环境中expose挺鸡肋的。
expose和-大P的时候使用才有用,小p就没用
Dockerfile3
做docker镜像的时候,可以指定env环境变量
run表示运行命令的,cmd也表示执行命令,但是有本质的不同,如果想要目标镜像安装某个程序包或者添加一个用户账号之类的,启动之后执行完了
应该构建的时候执行,需要用run
镜像启动以后的命令cmd,指定镜像启动以后,默认执行什么程序
ENV定义环境变量,VER是key,这个环境变量既可以docker变量里使用,也可以在dockerfile里用。
RUN就是在构建镜像的时候,帮你执行一些可执行命令
是一个bind软件
本地没有,就要从远端拉取centos镜像了
官网的centos指向8了,latest这个指针指向了centos8
默认用8的不行
改成centos7
以前centos动不动300M,现在官方入驻了,centos也小了,可以考虑上生产了
这里提示还是没有
改成6试试
宿主机看看bind软件是否更新
还是没成,可能这里是9.4
改成11.4,继续使用centos7
开始构建
是安装到镜像里,并不是启动容器,固化成一个只读层
验证一下
printenv有这个环境变量,这个环境变量既可以dockerfile里用,也可以docker容器里用
查看bind是否安装
Dockerfile4
RUN这个指令是在构建镜像的时候,帮你执行操作
CMD是启动容器的时候运行的命令。
之前在alpine的镜像的时候,-d,run不起来,一run就退出,没有一个进程在容器里,所以需要dockerfile里需要一个显式的进程执行在容器前台
当容器根据dockerfile启动的时候,用的是httpd -D FOREGROUND
安装httpd中
现在这个httpd镜像就出来了
现在run起来,83端口映射里面的80端口,用的镜像是oldboy1103/httpd
访问83端口看看
指定CMD命令,需要centos不用/bin/bash启动了,指定启动镜像的时候就用httpd -D FOREGROUND
NETRYPOINT,
每一个docker容器都有一个默认的CMD命令,如果启动这个镜像不指定CMD命令,默认走/entrypoint.sh这个脚本
先进到httpd镜像里去
用CMD命令启动了一个apache,这里可以修改/entrypoint.sh这个可执行文件可以启动nginx
把entrypoint脚本加到容器里的/entrypoint.sh。
不指定cmd应该是run一下就退出,所以用entrypoint的方法
一定加上可执行权限
现在就有这个镜像文件了
现在run起来,现在就横在这里了,因为有/sbin/nginx -g "daemon off
没有指定端口,先kill掉,再重启一个
映射出来
访问84
solomon就是docker的CTO,喜欢用自己的名字,这是一个可执行文件。
也就是在不指定CMD的时候,也可以直接指定entrypoint.sh放到docker容器的/entrypoint.sh,这是一个脚本,就可以按照这个脚本执行你想要的操作,比CMD操作灵活,因为CMD要堆一堆命令,不如写一个shell脚本。
其实还有args指令,可以给CMD和ENTRYPOINT传参。也就是entrypoint需要传参才起来
Dockerfile综合实验
也可以用ADD把entrypoint.sh放过去,然后CMD执行容器里的entrypoint指令
build出来
这里应该运行结束跟entrypoint指令是一样的,放在前台了
ps -a查看也是起来了
删除
有个问题,就是替换掉 如果使用其他命令,就把CMD顶掉了
如果用entrypoint,之前的mynginx镜像是有entrypoint指令,就替换不掉,走的还是entyrpoint指令
删除容器
新的docker-ce里面的命令,比如containers ,就比较不习惯
USER 用root启动,
ENV 环境变量,
RUN 调整一下时区,构建镜像的时候,帮你执行操作
WORKDIR 工作目录
ADD 把index文件放到容器指定目录下
ADD 就是配置一个nginx配置文件
expose 映射80端口出去
CMD 容器运行的命令
做一下配置文件
开始构建,docker build . 根据当前目录构建,-t 标签
-P把和暴露的端口进行映射
起来了
自定义一个dns解析域
可以-小p直接映射到80
这样就可以了
用kubectl访问k8s其实都是做域名的
用k8s不用自建DNS的话非常麻烦
详解Docker的四种网络模型
docker网络模型大致分为4种,nat,bridge,none,host
默认NAT,通过宿主机上的docker0网络设备,然后去nat出的网络,这个是在daemon.js里配置的一个网段,docker的网络和宿主机的网络是一个nat的关系
docker封装的服务可能不对外提供网络接口,所以不需要docker里有网络设备
k8s比较适合编排无状态服务,或者是不需要扩容的,所以不适合mysql
host是docker和宿主机在同一个网络,这个10。4.7.5在docker容器里也能看到,跟宿主机保持一致。
容器隔离6个名称空间(uts,ipc,mount,net,usr,pid),这里没有隔离net,宿主机和容器保持一致就行了
联合网络在k8s用的比较广泛,几个容器共享一个网络名称空间
启动一个容器
把没用的删除
debian系统使用apt-get,所以安装nettools,就有ifconig命令了
再启动一个,使用81的名称空间
敲一下网络看到的应该是跟之前一样的地址这两个容器其实共享了网络名称空间
百分之90部署的时候都是nat
网络名称空间有4种