在之前的几篇文章中, 主要还是讲解了关于简单的 docker 容器该如何进行管理和操作及 k8s 上手避坑, 在接下来的这篇文章开始, 我们将继续对 k8s 模块的学习
pod 是啥
在 k8s 里面, 有很多新的技术概念, 其中有一个东西被称之为 pod.pod 是 k8s 集群里面运行和部署的最小单元, 它的设计理念是, 一个 pod 可以承载多个容器, 并且共享网络地址和文件系统, 内部的容器通过进程间的通信相互访问.
官方图片附上:
复制控制器 (Replication Controller,RC)
通常我们在 k8s 集群里面会有成千上百个 pod, 那么对于 pod 的管理也是需要有一定的机制, k8s 内部有个叫做 RC(Replication Controller) 的复制控制器.
RC 主要的是监控 pod 节点的数目, 当我们在启动 pod 的时候希望有多个 pod 副本, 可以使用 RC 来控制启动的数目, 如果期间有部分 pod 挂掉了, RC 会自动进行重启 pod.
k8s 里面常见的 pod 操作场景
1. 在实操的过程中, 如果你遇到了下边的这种情况, 某个 pod 一直起不来
- [root@localhost ~]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- MySQL-rc-p8blq 0/1 ErrImagePull 0 16h
- nginx 1/1 Running 0 29h
- nginx-deployment-54f57cf6bf-f9p92 0/1 ContainerCreating 0 77s
- nginx-deployment-54f57cf6bf-mqq7x 0/1 ImagePullBackOff 0 18m
- nginx-deployment-9f46bb5-kwxwh 0/1 ImagePullBackOff 0 13m
- tomcat-565cd88dc7-qlqtk 1/1 Running 0 2d3h
这个时候 pod 可能会出现启动失败的情况, 那么这个时候该如何去终止对应的 pod 呢?
通过以下的命令来对容器进行删除即可:
- [root@localhost k8s]# kubectl delete -f ./MySQL-rc.YAML
- replicationcontroller "mysql-rc" deleted
- [root@localhost k8s]# kubectl delete -f ./MySQL-svc.YAML
- service "mysql-svc" deleted
- [root@localhost k8s]# kubectl delete -f ./nginx-deployment.YAML
- deployment.apps "nginx-deployment" deleted
- [root@localhost k8s]# kubectl get pods
- NAME READY STATUS RESTARTS AGE
- nginx 1/1 Running 0 29h
- tomcat-565cd88dc7-qlqtk 1/1 Running 0 2d3h
2. 如何运行单容器的 pods
kubectl run example --image=nginx
3. 查看某个 pod 详细信息
- [root@localhost k8s]# kubectl get pod nginx -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- nginx 1/1 Running 0 29h 172.17.0.7 minikube <none> <none>
4. 查看某 pod 里面的详情描述内容
- [root@localhost k8s]# kubectl describe pod nginx
- Name: nginx
- Namespace: default
- Priority: 0
- Node: minikube/10.1.10.51
- Start Time: Mon, 02 Dec 2019 09:49:28 +0800
- Labels: App=pod-example
- Annotations: <none>
- Status: Running
- IP: 172.17.0.7
- IPs:
- IP: 172.17.0.7
- Containers:
- web:
- Container ID: docker://53d066b49233d17724b8fd0d5a4d6a963f33e6ea4e0805beb7745ee267683ed8
- Image: nginx
- Image ID: docker-pullable://nginx@sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566
- Port: 80/TCP
- Host Port: 0/TCP
- State: Running
- Started: Mon, 02 Dec 2019 09:51:22 +0800
- Ready: True
- Restart Count: 0
- Environment: <none>
- Mounts:
- /var/run/secrets/kubernetes.io/serviceaccount from default-token-7mltd (ro)
- Conditions:
- Type Status
- Initialized True
- Ready True
- ContainersReady True
- PodScheduled True
- Volumes:
- default-token-7mltd:
- Type: Secret (a volume populated by a Secret)
- SecretName: default-token-7mltd
- Optional: false
- QoS Class: BestEffort
- Node-Selectors: <none>
- Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
- node.kubernetes.io/unreachable:NoExecute for 300s
- Events: <none>
5. 替换 pod 对应的配置规则文件
kubectl replace --force -f 规则文件
6. 假设说你在操控 pod 节点的过程中不小心写错了镜像的地址, 导致 pod 启动失败, 这个时候我们可以删除机器上边的某个 pod 节点, 例如:
删除一个 name 为 nginx 的 pod 节点:
- [root@localhost k8s]# kubectl delete pod nginx
- pod "nginx" deleted
7. 删除某台机器上边 deployment 信息:
- [root@localhost k8s]# kubectl delete deployment tomcat
- deployment.apps "tomcat" deleted
8. 多容器 pod 启动的步骤
我们启动多个容器的 pod 时候, 最好使用 create 命令来操作, 并且在创建的时候最好是使用 YAML(或者 JSON 格式) 这种文件来对容器的启动进行管理:
kubectl create -f FILE
通常启动 pod 的 YAML 文件的格式基本如下:
- apiVersion: v1
- kind: Pod
- metadata:
- name: rss-site
- labels:
- App: Web
- spec:
- containers:
- name: 容器 1
image: 镜像名 1
- ports:
- - containerPort: 80
- name: 容器 1
image: 镜像名 2
- ports:
- - containerPort: 88
- spec:
如果启动过程中需要有多个 docker 容器, 那么就写多个 name,image,ports 这类配置即可.
在 k8s 的 pod 启动过程中, 如果出现多次发现镜像拉取失败的情况, 通常是因为镜像源地址出错, 这时候需要重置 docker 镜像源地址:
- # vi /etc/docker/daemon.JSON
- {
- "registry-mirrors": ["http://hub-mirror.c.163.com"]
- }
- systemctl restart docker.service
设置好这份 JSON 文件之后, 我们进行 restart 操作即可.
编写好了 YAML 文件之后, 再次使用 kubectl create -f FILE 命令即可.
最后通过 kubectl get pod 指令来验证 pod 的状态即可.
同理, 如果我们需要用 pod 装载 java 程序的话, 例如说是 springboot 应用, 只需要将 springboot 应用打包成 docker 镜像, 然后在 YAML 配置里面引入就好了.
9. 查看 pod 内部节点的日志信息
- kubectl logs <pod_name>
- kubectl logs -f <pod_name> #类似 tail -f 的方式查看 (tail -f 实时查看日志文件 tail -f 日志文件 log)
前边我们主要都是讲解一些基于容器化技术的实战, 操作了这么多容器化的 API 命令, 其背后架构的设计思路却又是怎样的呢?
10.kubernetes 的基本架构
用一句简单的话语来介绍, kubernetes 就是一个容器的集群管理系统, 通过 kubernetes 可以实现对于容器集群化的自动化部署, 自动化扩容, 维护等作用.
kubernetes 集群是由一个 master 来负责对各个节点进行管理的, 其中被管理的各个 node 节点可能会是一些虚拟机或者小型机器. 在每个 node 节点上都会运作有各种各样的 pod, 而 pod 通常会是各种各样的 docker 容器.
基本的架构图如下所示:
Master 模块
kubectl 主要的作用是对 kubernetes 发送命令, 通过使用 apiserver 来调用 kubernets 对内部的各个 node 节点进行部署和控制.
ApiServer 的主要工作就是对各个 node 节点进行增删改查, 提到对节点数据的操作, 我们不得不得说明一下 etcd.etcd 主要是存储一些节点的数据信息, 并且每次 kubectl 发送过来的指令都会被 apiserver 先存储到 etcd 中.
Controller manager 的作用主要是监控各个容器的情况. Controller manager 会通过监听 API Server 里面的提供的一个 List Watch 接口来监控各个集群资源的数据, 从而调整资源的状态.
举个栗子来讲:
在成百上千的微服务系统中, 假设说某个节点出现了 crash, 那么这个时候 Controller manager 就会自动地进行节点的修复, 故障转移, 这样就能很好地减轻了运维人员的压力.
Scheduler 主要是一个调度的作用, 将容器部署到指定的机器上边, 然后将 pod 和 node 资源进行映射, 当节点数目变多了之后, scheduler 会自动进行资源的分配. 所以说白了, Scheduler 是老大, 它来决定每个 pod 要放置在哪个 node 上边, 并且命令 kubelet 进行容器的部署.
Node 模块
Node 是 k8s 的工作节点, Node 一般是一个虚拟机或者物理机, 每个 node 上都运行三个服务, 分别是 Container runtime,kubelet,kube-proxy 三类.
kubelet 主要是负责接收 master 的命令, 并且执行, 同时还要维护容器的生命周期.
kube-proxy 主要的作用就是负责负载均衡, 处理流量的转发问题.
Container runtime 是负责镜像管理以及 pod 和容器的真正运行.
从 K8s 的系统架构, 技术概念和设计理念, 我们可以看到 K8s 系统最核心的两个设计理念: 一个是容错性, 一个是易扩展性. 容错性实际是保证 K8s 系统稳定性和安全性的基础, 易扩展性是保证 K8s 对变更友好, 可以快速迭代增加新功能的基础.
来源: https://www.cnblogs.com/javazhiyin/p/12082992.html