k8s pod部署到不同node_容器&k8s相关概念笔记

12bd57840e6e8c9f0df588789cc6f527.png

大纲

  • 一、容器和虚拟机的区别?
  • 二、容器是跑在宿主机的一个进程为什么还要镜像OS?
  • 三、为什么容器里只能跑一个进程?
  • 四、沙盒技术原理
  • 五、什么是容器编排(K8S)?
  • 六、K8S集群架构
  • 七、什么是Pod?
  • 八、K8S的组件 kubelet 是什么?为什么不能部署在容器里?
  • 九、K8S发挥的作用
  • 十、K8S核心概念
  • 十一、Pod,Deployment,ReplicaSet,Service的关系
  • 十二、网络拓扑复习
  • 十二、虚拟机转镜像
  • 十三、如何给POD暴露服务

一、容器和虚拟机的区别?

f13a6ef3778f61ddfe55af91ae9f823b.png

二、容器是跑在宿主机的一个进程为什么还要镜像OS?

xds2000 - 数人科技CTO

赞同来自: 田浩浩 、wangzi19870227 、azhai 、DaoCloud 、石海旭 更多 »
这个问题可能只有我能回答了。请让我慢慢道来。
首先我来回答一下问题一,Container内需不需要OS?
Container不是一个VM技术,所以和OS没有关系。如果我没有理解错,这个Container应该指的是Docker Run出的运行环境,因为在里面我们可以运行一些命令,让使用者以为它就是一个完整的OS环境。这是不对的。其实Docker只是一个进程。当你使用docker exec登录进去的也只是一个Terminal的模拟环境。它不是真实的OS。正因为它不是OS,所以它是直接调用主机的Kernel的。而Container本身只是一个系统进程。
好了,我来回答第二个问题:为何需要OS的基础镜像?
首先,OS的问题上面已经解释过了,它不是一个OS,但为何需要OS的基础镜像?其实这里的基础镜像是一个包含rootfs的镜像。Kernel启动后是需要把启动文件解压到rootfs上的,然后kernel找到init文件启动就可以得到一个Linux环境了,Docker做的事情就是模拟这个过程,让kernel给出一个独立的隔离环境。
mkdir testfs
curl -sSL github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar | tar -xC testfs
cd testfs
你可以看一下一个rootfs的解压后的目录就能大致了解我说的意思了。

附:http://dockone.io/question/6

三、为什么容器里只能跑一个进程?

由于一个容器的本质就是一个进程,用户的应用进程实际上就是容器里 PID=1 的进程,也是其他后续创建的所有进程的父进程。这就意味着,在一个容器中,你没办法同时运行两个不同的应用,除非你能事先找到一个公共的 PID=1 的程序来充当两个不同应用的父进程,这也是为什么很多人都会用 systemd 或者 supervisord 这样的软件来代替应用本身作为容器的启动进程。

但是,在后面分享容器设计模式时,我还会推荐其他更好的解决办法。这是因为容器本身的设计,就是希望容器和应用能够同生命周期,这个概念对后续的容器编排非常重要。否则,一旦出现类似于“容器是正常运行的,但是里面的应用早已经挂了”的情况,编排系统处理起来就非常麻烦了。

四、沙盒技术原理

而Docker 镜像解决的,恰恰就是打包这个根本性的问题。 所谓 Docker 镜像,其实就是一个压缩包。但是这个压缩包里的内容,比 PaaS 的应用可执行文件 + 启停脚本的组合就要丰富多了。实际上,大多数 Docker 镜像是直接由一个完整操作系统的所有文件和目录构成的,所以这个压缩包里的内容跟你本地开发和测试环境用的操作系统是完全一样的。

五、什么是容器编排(K8S)?

容器编排就是根据具体的任务(业务)描述容器(资源)的组织,包含数量,配置,网络拓扑等,更进一步地说,我还希望 Kubernetes 能给我提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。在 Compose 项目中,你可以为这样的两个容器定义一个“link”,而 Docker 项目则会负责维护这个“link”关系,其具体做法是:Docker 会在 Web 容器中,将 DB 容器的 IP 地址、端口等信息以环境变量的方式注入进去,供应用进程使用

而 Kubernetes 项目所擅长的,是按照用户的意愿和整个系统的规则,完全自动化地处理好容器之间的各种关系。这种功能,就是我们经常听到的一个概念:编排。

例子:

Cassandra 容器之间的编排关系。比如,哪些 Cassandra 容器是主,哪些是从?主从容器如何区分?它们之间又如何进行自动发现和通信?Cassandra 容器的持久化数据又如何保持,等等。

六、K8S集群架构

典型的 Kubernetes 集群包含一个 master 和多个 node。Master 是控制集群的中心,node 是提供 CPU、内存和存储资源的节点。Master 上运行着很多进程,包括面向用户的 API 服务、负责维护集群状态的 Controller Manager、负责调度任务的 Scheduler 等。每个 node 上运行着维护 node 状态并和 master 通信的 kubelet,以及实现集群网络服务的 kube-proxy,相关连接:nodes

f710845cf34c5b02524ff491d36b6428.png

30fe6dc7a05f406b464d696d332cdf6c.png

七、什么是Pod?

在常规环境下,这些应用往往会被直接部署在同一台机器上,通过 Localhost 通信,通过本地磁盘目录交换文件。而在 Kubernetes 项目中,这些容器则会被划分为一个“Pod”,Pod 里的容器共享同一个 Network Namespace、同一组数据卷,从而达到高效率交换信息的目的。

Pod也是对容器的封装,给容器装饰抓手,可以一个容器一个Pod也可以多个容器封装成一个Pod

八、K8S的组件 kubelet 是什么?为什么不能部署在容器里?

如果 kubelet 本身就运行在一个容器里,那么直接操作宿主机就会变得很麻烦。对于网络配置来说还好,kubelet 容器可以通过不开启 Network Namespace(即 Docker 的 host network 模式)的方式,直接共享宿主机的网络栈。可是,要让 kubelet 隔着容器的 Mount Namespace 和文件系统,操作宿主机的文件系统,就有点儿困难了。在每个节点(node)上都要运行一个 worker 对容器进行生命周期的管理,这个 worker 程序就是 kubelet

九、K8S发挥的作用

96bf4139a2efb83d6d3e6349bd6a05d2.png

十、K8S核心概念

上图可以看到如下组件,使用特别的图标表示Service和Label:http://dockone.io/article/932

  • Pod
  • Container(容器)
  • Label(

741b33c20ea2873f112fe25f984f0435.png

)(标签)

  • Replication Controller(复制控制器)
  • Service(

5b21e68bf816813a2b1ec15cbbe2a5dd.png

)(服务)

  • Node(节点)
  • Kubernetes Master(Kubernetes主节点)

十一、Pod,Deployment,ReplicaSet,Service的关系

ac123cf20f86e88c9236e640b80ab149.png

十二、网络拓扑复习

Docker Overlay网络的一些总结

baad9d07a21e1e617b74472a0e1704f8.png

269c0759bf2e179a308c199deca5dc2c.png

十二、虚拟机转镜像

$ cd /
$ sudo tar cf /img.tar --exclude=/img.tar --one-file-system /
或者
$ sudo mount -o loop partition.dump /mnt
$ sudo tar cf $(pwd)/img.tar -C /mnt .
$ sudo umount /mnt
------
FROM scratch
ADD img.tar /

参考:https://www.centos.bz/2016/11/converting-vm-to-docker-container/

十三、如何给POD暴露服务

//创建pod kubectl create -f pod.yml, kubectl get pods
apiVersion: v1
kind: Pod
metadata:
 name: k8s-demo
spec:
 containers:
 - name: k8s-demo
 image: k8s-demo:0.1
 ports:
 - containerPort: 80
//虽然这个 pod 在运行,但是我们是无法像之前测试 Docker 时一样用浏览器访问它运行的服务的。可以理解为 pod 都运行在一个内网,我们无法从外部直接访问。要把服务暴露出来,我们需要创建一个 Service。
//Service 的作用有点像建立了一个反向代理和负载均衡器,负责把请求分发给后面的 pod。
//创建一个 Service 的定义文件 svc.yml:
apiVersion: v1
kind: Service
metadata:
 name: k8s-demo-svc
 labels:
 app: k8s-demo
spec:
 type: NodePort
 ports:
 - port: 80
 nodePort: 30050
 selector:
 app: k8s-demo
//这里的定义是所有包含「app: k8s-demo」这个标签的 pod。然而我们之前部署的 pod 并没有设置标签:所以要先更新一下 pod.yml,把标签加上,kubectl apply -f pod.yml
apiVersion: v1
kind: Pod
metadata:
 name: k8s-demo
 labels:
 app: k8s-demo
spec:
 containers:
 - name: k8s-demo
 image: k8s-demo:0.1
 ports:
 - containerPort: 80
//kubectl create -f svc.yml
-------------------------------------
//在正式环境中我们需要让一个服务不受单个节点故障的影响,并且还要根据负载变化动态调整节点数量,所以不可能像上面一样逐个管理 pod。Kubernetes 的用户通常是用 Deployment 来管理服务的。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
 name: k8s-demo-deployment
spec:
 replicas: 10
 minReadySeconds: 10
 strategy:
 type: RollingUpdate
 rollingUpdate:
 maxUnavailable: 1
 maxSurge: 1
 template:
 metadata:
 labels:
 app: k8s-demo
 spec:
 containers:
 - name: k8s-demo-pod
 image: k8s-demo:0.2
 ports:
 - containerPort: 80
//这里有两个改动,第一个是更新了镜像版本号 image: k8s-demo:0.2,第二是增加了 minReadySeconds: 10 和 strategy 部分。新增的部分定义了更新策略:minReadySeconds: 10 指在更新了一个 pod 后,需要在它进入正常状态后 10 秒再更新下一个 pod;maxUnavailable: 1 指同时处于不可用状态的 pod 不能超过一个;maxSurge: 1 指多余的 pod 不能超过一个。这样 Kubernetes 就会逐个替换 service 后面的 pod
//kubectl apply -f deployment.yml --record=true  --record=true 让 Kubernetes 把这行命令记到发布历史中备查
//kubectl rollout history deployment k8s-demo-deployment
//$ kubectl rollout undo deployment k8s-demo-deployment --to-revision=1 回滚
 
//$ kubectl rollout status deployment k8s-demo-deployment

参考:https://1byte.io/developer-guide-to-docker-and-kubernetes/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值