Kubernetes集群架构
Kubernetes集群包含master节点和node节点,应用部署在node节点上,且可以通过配置选择应用部署在某些特定的节点上。
Kubernetes集群的架构如下所示。
Master节点
Master节点是集群的控制节点,由API Server、Scheduler、Controller Manager和ETCD四个组件构成。
API Server:各组件互相通讯的中转站,接受外部请求,并将信息写到ETCD中。
Controller Manager:集群内部的管理控制中心,负责集群内的Node,Pod副本,服务端点(endpoint),命名空间(namespace)等的管理,当某个Node意外宕机,CM会及时发现此故障并执行自动化修复流程,确保集群始终处于预期的工作状态。
Scheduler负责节点资源管理,接收来自kube-apiserver创建Pods的任务,收到任务后它会检索出所有符合该Pod要求的Node节点(通过预选策略和优选策略),开始执行Pod调度逻辑。调度成功后将Pod绑定到目标节点上。
4.Etcd
etcd在kubernetes集群是用来存放数据并通知变动的。
Kubernetes中没有用到数据库,它把关键数据都存放在etcd中,这使kubernetes的整体结构变得非常简单。在kubernetes中,数据是随时发生变化的,比如说用户提交了新任务、增加了新的Node、Node宕机了、容器死掉了等等,都会触发状态数据的变更。状态数据变更之后呢,Master上的kube-scheduler和kube-controller-manager,就会重新安排工作,它们的工作安排结果也是数据。这些变化,都需要及时地通知给每一个组件。etcd有一个特别好用的特性,可以调用它的api监听其中的数据,一旦数据发生变化了,就会收到通知。有了这个特性之后,kubernetes中的每个组件只需要监听etcd中数据,就可以知道自己应该做什么。kube-scheduler和kube-controller-manager呢,也只需要把最新的工作安排写入到etcd中就可以了,不用自己费心去逐个通知了
Node节点
Node节点是集群的计算节点,即运行容器化应用的节点。
**kubelet:**kubelet主要负责同Container Runtime打交道,并与API Server交互,管理节点上的容器。
**kube-proxy:**应用组件间的访问代理,解决节点上应用的访问问题。
**Container Runtime:**容器运行时,如Docker,最主要的功能是下载镜像和运行容器。
1、陈述式管理方法–主要依赖命令行CLI工具进行管理
kubectl之命名空间相关命令
kubectl get ns #其中ns是namespace的缩写,查看所有的名称空间
kubectl create namespace + 命名空间 # 增加命名空间
kubectl之查看某一空间下相关资源
kubectl get all -n + 命名空间 #看到某一个命名空间下的所有资源,包括pod、service资源、pod控制器
创建deployment(pod控制器)
1、创建pod控制器
kubectl create deployment nginx-name --image=********
# nginx-name pod控制器名字
# ******** 表示私有仓库地址image路径
2、查看某一空间下所有deployment
kubectl get deployment -n +命名空间
3、查看某一空间下所有pod
kubectl get pods -n +命名空间
kubectl get pods -o wide-n +命名空间 #显示更加详细的消息
kubectl get deployment -o wide-n +命名空间 #显示更加详细的消息
debug:
在创建完后发现无法将镜像拉取下来,报错:Failed to pull image “115.29.196.126/public/nginx:v1.7.9”: rpc error: code = Unknown desc = Error response from daemon: Get https://115.29.196.126/v2/: dial tcp 115.29.196.126
于是通过查看日志,其命令为 kubectl describe pod nginx-1-66c594c5b8-vvwk6 -n kube-public。发现这个pod是部署在node-1节点上,且这个节点没有在etc/docker/daemon.json中的配置 “insecure-registries”: [“115.29.196.126”]导致无法从私有仓库拉取镜像,然后通过docker login+私有镜像库ip后即可启动。
查看相关pod控制器,pod详细描述,类似于日志
kubectl describe deployment +pod控制器名 + -n 命名空间
kubectl describe pod + pod名 -n 命名空间
删除pod控制器、pod,进入pod
kukectl delete deployment + pod控制器名称 -n 指定孔空间
kukectl delete pod + pod名称 -n 指定孔空间
kubectl exec -it pod名称 /bin/bash -n 命名空间 #进入指定的pod,类似于进入docker
管理service资源、创建service
kubectl expose deployment pod控制器名称 --port=80 -n + 命名空间
kubectl get svc -n + 命名空间
kubectl describe svc -n +命名空间
注:从图片中可以看到service为各个pod统一了访问地址,访问到这个ip的请求都会被随机分配到各个pod中,同一个pod控制器的pod都是同一个服务,可从其镜像拉取路径判别。
给指定pod控制器扩容
kubectl scale deployment nginx-1 --replicas=2 -n + 命名空间 # nginx-1为pod控制器名称
可通过ipvsadm -Ln查看相对应的service ip对应的pod转发ip
小结:
1、kubernetes集群管理集群资源的唯一入口是通过相应的方法调用apiserver的接口
2、kubectl是管方的CLI命令行工具,用于与apiserver进行通信,将用户在命令行输入的命令,组织并转化为apiserver能识别的信息,进而实现管理k8s各种资源的一种有效途径
声明式资源管理方法
声明式资源管理方法依赖于—资源配置清单(yaml、json)
查看资源配置清单的方法
kubectl get svc nginx-1 -o yaml -n +命名空间
解释资源配置清单
kubectl explain service.字段名 #后面添加字段名,对其进行解释
创建资源配置清单
vim /root/nginx-ds-svc.yaml
应用资源配置清单
kubectl apply -f nginx-svc.yaml #离线修改
kubectl edit service nginx-ds -n +命名空间 #在线修改
查看某个pod的yaml文件
kubectl get pods pod名称 -o yaml -n +命名空间 #-o yaml 以yaml格式显示结果 -o json 以json格式显示
kubectl get deployment pod控制器名称 -o yaml -n +命名空间 #同上
删除指定的service
kubectl delete service +指定的service服务 #陈述式删除
kubectl delete -f +相关yaml文件 #声明式删除,删除配置清单
声明式资源管理方法小结
1、声明式资源管理方法,依赖于统一资源配置清单文件对资源进行管理
2、对资源的管理,是通过事先定义在统一资源配置清单内,再通过陈述式命令应用到k8s集群里
3、语法格式:kubectl create/apply/delete -f /path/to/yaml
资源配置清单的学习方法:
多看别人(官方)写的,能读懂
能照着现成的文件改着用
遇到不懂得,用kubectl explain。。。。查
初学者切记上来就无中生有,自己憋着写
k8s的imagePullSecrets如何生成及使用
情景再现:在运行yaml文件的结束成功后,通过kubectl describe时候发现镜像一直拉取失败,但是通过docker pull +镜像项目路径又可以成功拉取镜像,这时候主要是k8s没有权限去私有仓库拉取镜像导致,需要配置secret,具体操作如下所示:
概述
公司的docker仓库(harbor),是私有的,需要用户认证之后,才能拉取镜像。
生成secret
登录docker
登录到k8s master节点,先登录docker
root@k8s-master:~# docker login 192.168.10.122 -u admin -p Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get https://192.168.10.122/v2/: dial tcp 192.168.10.122:443: connect: connection refused
注意:出现这个报错,是由于harbor为了安全性考虑,默认是需要https证书支持的
但是我们可以通过一个简单的办法解决
修改 /etc/docker/daemon.json 文件
vim /etc/docker/daemon.json
内容如下:
{"insecure-registries": ["192.168.10.122"]}
重新加载docker配置
/etc/init.d/docker reload
再次登录
root@k8s-master:~# docker login 192.168.10.122 -u admin -p Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
提示登录成功。
登录过程创建或更新一个包含授权令牌的config.json文件。
查看config.json文件:
cat ~/.docker/config.json
输出包含类似以下内容的部分:
{
"auths": {
"192.168.10.122": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.1 (linux)"
}
}
注意:如果您使用Docker凭据存储,您将看不到该auth条目,而是看到一个以存储名称为值的credsstore条目。
基于现有Docker凭据创建secret
kubernetes集群使用docker注册表类型的秘密对容器注册表进行身份验证,以获取私有映像。
如果您已经运行了Docker登录,则可以将该凭证复制到Kubernetes中:
kubectl create secret generic harborsecret \
--from-file=.dockerconfigjson=/root/.docker/config.json \
--type=kubernetes.io/dockerconfigjson
注意:主要修改红色部分。
harborsecret 表示key名
/root/.docker/config.json 表示docker认证文件,**注意要写绝对路径。**
查看内容
kubectl get secrets harborsecret --output="jsonpath={.data.\.dockerconfigjson}" | base64 -d
输出:
{
"auths": {
"192.168.10.122": {
"auth": "YWRtaW46SGFyYm9yMTIzNDU="
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.1 (linux)"
}
}
要了解刚刚创建的regcred秘密的内容,请从以yaml格式查看秘密开始:
kubectl get secret harborsecret --output=yaml
输出:
apiVersion: v1
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEwLjEyMiI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy4xIChsaW51eCkiCgl9Cn0=
kind: Secret
metadata:
creationTimestamp: "2019-08-30T06:14:10Z"
name: harborsecret
namespace: default
resourceVersion: "6128"
selfLink: /api/v1/namespaces/default/secrets/harborsecret
uid: 76e16e61-a6b9-4a47-a842-e884cf6f468d
type: kubernetes.io/dockerconfigjson
**在demployment yaml文件中的使用示例**
...
spec:
imagePullSecrets:
- name:harborsecret
containers:
- name: eureka
image: 192.168.10.122/library/alpine:latest
...
如果需要删除secret,使用命令
kubectl delete secrets harborsecret
注意,要在每个节点的/etc/docker下的配置文件中更改私有仓库的地址