Kubernetes入门

完成

image-20210102164249145

介绍

img

官方文档

Kubernetes 组件

当你部署完 Kubernetes, 即拥有了一个完整的集群。

一个 Kubernetes 集群包含 集群由一组被称作节点的机器组成。这些节点上运行 Kubernetes 所管理的容器化应用。集群具有至少一个工作节点。

工作节点托管作为应用负载的组件的 Pod 。控制平面管理集群中的工作节点和 Pod 。 为集群提供故障转移和高可用性,这些控制平面一般跨多主机运行,集群跨多个节点运行。

本文档概述了交付正常运行的 Kubernetes 集群所需的各种组件。

这张图表展示了包含所有相互关联组件的 Kubernetes 集群。

components-of-kubernetes

控制平面组件(Control Plane Components)

控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。

控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件,并且不会在此计算机上运行用户容器。 请参阅构建高可用性集群 中对于多主机 VM 的设置示例。

kube-apiserver

API 服务器是 Kubernetes 控制面的组件, 该组件公开了 Kubernetes API。 API 服务器是 Kubernetes 控制面的前端。

Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平伸缩,也就是说,它可通过部署多个实例进行伸缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。

etcd

etcd 是兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。

您的 Kubernetes 集群的 etcd 数据库通常需要有个备份计划。

要了解 etcd 更深层次的信息,请参考 etcd 文档

kube-scheduler

主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。

调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。

kube-controller-manager

在主节点上运行 控制器 的组件。

从逻辑上讲,每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。

这些控制器包括:

  • 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
  • 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。
  • 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)。
  • 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌.

cloud-controller-manager

云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件。 云控制器管理器允许您链接聚合到云提供商的应用编程接口中, 并分离出相互作用的组件与您的集群交互的组件。

cloud-controller-manager 仅运行特定于云平台的控制回路。 如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的环境中不需要云控制器管理器。

kube-controller-manager 类似,cloud-controller-manager 将若干逻辑上独立的 控制回路组合到同一个可执行文件中,供你以同一进程的方式运行。 你可以对其执行水平扩容(运行不止一个副本)以提升性能或者增强容错能力。

下面的控制器都包含对云平台驱动的依赖:

  • 节点控制器(Node Controller): 用于在节点终止响应后检查云提供商以确定节点是否已被删除
  • 路由控制器(Route Controller): 用于在底层云基础架构中设置路由
  • 服务控制器(Service Controller): 用于创建、更新和删除云提供商负载均衡器

Node 组件

节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。

kubelet

一个在集群中每个节点上运行的代理。 它保证容器都运行在 Pod 中。

kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。

kube-proxy

kube-proxy 是集群中每个节点上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。

kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。

如果操作系统提供了数据包过滤层并可用的话,kube-proxy 会通过它来实现网络规则。否则, kube-proxy 仅转发流量本身。

容器运行时(Container Runtime)

容器运行环境是负责运行容器的软件。

Kubernetes 支持多个容器运行环境: DockercontainerdCRI-O 以及任何实现 Kubernetes CRI (容器运行环境接口)

插件(Addons)

插件使用 Kubernetes 资源(DaemonSetDeployment等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system 命名空间。

下面描述众多插件中的几种。有关可用插件的完整列表,请参见 插件(Addons)

DNS

尽管其他插件都并非严格意义上的必需组件,但几乎所有 Kubernetes 集群都应该 有集群 DNS, 因为很多示例都需要 DNS 服务。

集群 DNS 是一个 DNS 服务器,和环境中的其他 DNS 服务器一起工作,它为 Kubernetes 服务提供 DNS 记录。

Kubernetes 启动的容器自动将此 DNS 服务器包含在其 DNS 搜索列表中。

Web 界面(仪表盘)

Dashboard 是Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除。

容器资源监控

容器资源监控 将关于容器的一些常见的时间序列度量值保存到一个集中的数据库中,并提供用于浏览这些数据的界面。

集群层面日志

集群层面日志 机制负责将容器的日志数据 保存到一个集中的日志存储中,该存储能够提供搜索和浏览接口。

一个K8S系统,通常称为一个K8S集群(Cluster)

这个集群主要包括两个部分:

  • 一个Master节点(主节点)
  • 一群Node节点(计算节点)
img
img
img

Master节点包括API Server、Scheduler、Controller manager、etcd。

API Server是整个系统的对外接口,供客户端和其它组件调用,相当于“营业厅”。

Scheduler负责对集群内部的资源进行调度,相当于“调度室”。

Controller manager负责管理控制器,相当于“大总管”。

Node节点包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可选),还有就是Pod

Pod是Kubernetes最基本的操作单元。一个Pod代表着集群中运行的一个进程,它内部封装了一个或多个紧密相关的容器。除了Pod之外,K8S还有一个Service的概念,一个Service可以看作一组提供相同服务的Pod的对外访问接口

安装

Kubectl

$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
$ dnf install -y kubectl
$ kubectl version --client

Minikube(弃用)

$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-latest.x86_64.rpm
$ sudo rpm -ivh minikube-latest.x86_64.rpm
$ minikube config set driver docker
$ minikube start --driver=docker
# 需以非root运行
$ useradd minikuber
$ passwd minikuber
$ groupadd docker
$ su minikuber
$ sudo usermod -aG docker $USER && newgrp docker
# 会自动下载依赖并拉取k8s镜像
$ minikube start --driver=docker
# 查看状态
$ kubectl config current-context
$ kubectl get nodes
# 配置
$ eval $(minikube docker-env)
# 卸载后需执行
$ unset DOCKER_HOST
$ unset DOCKER_TLS_VERIFY
$ unset DOCKER_TLS_PATH
$ unset DOCKER_CERT_PATH

安装K8S集群(https://blog.51cto.com/3241766/2405624)

环境脚本

#!/bin/bash

#关闭防火墙
systemctl disable firewalld
systemctl stop firewalld

#关闭selinux
setenforce 0
#永久关闭
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/sysconfig/selinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

#禁用swap
swapoff -a
#永久禁用
sed -i "s/.*swap.*/#&/" /etc/fstab

#修改内核参数
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

#重新加载配置文件
sysctl --system

#配置阿里k8s yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

#更新缓存
dnf clean all -y && dnf makecache -y && dnf repolist -y

$ dnf install -y kubelet kubeadm kubectl
#kubelet 运行在集群所有节点上,用于启动Pod和容器等对象的工具
#kubeadm 用于初始化集群,启动集群的命令工具
#kubectl 用于和集群通信的命令行,通过kubectl可以部署和管理应用,查看各种资源,创建、删除和更新各种组件
#启动kubelet并设置开机启动
$ systemctl enable kubelet && systemctl start kubelet
$ kubeadm init --apiserver-advertise-address 10.100.6.140 --pod-network-cidr=10.244.0.0/16
$ kubectl apply -f document/kubernetes/kube-flannel.yml 
$ kubectl taint nodes --all node-role.kubernetes.io/master-
$ kubectl apply -f document/kubernetes/recommended.yaml 
#使用令牌登陆dashboard,获取令牌方式
$ kubectl describe secrets -n kube-system dashboard-admin
#创建应用。当前待解决挂载外部文件问题
$ kubectl create -f document/kubernetes/env/
#修改外部映射端口范围
$ vim /etc/kubernetes/manifests/kube-apiserver.yaml
#找到 --service-cluster-ip-range 这一行,在这一行的下一行增加 如下内容
- --service-node-port-range=1-65535
#生效
$ systemctl daemon-reload
$ systemctl restart kubelet

暂时使用Kompose进行Docker 到 Kubernetes

$ curl -L https://github.com/kubernetes/kompose/releases/download/v1.22.0/kompose-linux-amd64 -o kompose
$ chmod +x kompose
$ sudo mv ./kompose /usr/local/bin/kompose
# 使用方式 Run kompose convert in the same directory as your docker-compose.yaml file.
# 运行 kompose up 命令直接部署到 Kubernetes,或者跳到下一步,生成 kubectl 使用的文件。
$ kompose --file ./examples/docker-guestbook.yml up
# 要将 docker-compose.yml 转换为 kubectl 可用的文件,请运行 kompose convert 命令进行转换, 然后运行 kubectl create -f <output file> 进行创建。
$ kompose convert    
$ kubectl create -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml
# 你一旦将"复合(composed)" 应用部署到 Kubernetes,kompose down 命令将能帮你通过删除 Deployment 和 Service 对象来删除应用。 如果需要删除其他资源,请使用 'kubectl' 命令。
$ kompose --file docker-guestbook.yml down

容器挂载文件

挂载目录

NFS + PV + PVC。需注意PV核PVC需有相同的读写权限以及相同的storageClassName(可以设置为default)

挂载文件

ConfigMap

configmap是k8s的一个配置管理组件,可以将配置以key-value的形式传递,通常用来保存不需要加密的配置信息,加密信息则需用到Secret,主要用来应对以下场景:

  1. 使用k8s部署应用,当你将应用配置写进代码中,就会存在一个问题,更新配置时也需要打包镜像,configmap可以将配置信息和docker镜像解耦。
  2. 使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中单独一份配置的话,那么更新配置就很麻烦,使用configmap可以友好的进行配置共享。

其次,configmap可以用来保存单个属性,也可以用来保存配置文件。

可通过配置volumeMounts中的subPath属性,实现挂载单个文件

配置文件类。建议使用configMap的方式。而非目录或文件挂载。未知问题

创建

你可以通过命令kubectl create configmap -h帮助信息查看具体的创建。

configmap有三种常见创建方式:

**1. 通过yaml / json文件创建(推荐) **

这种是我比较推荐的方式,创建configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata: 
  name: test-conf
  namespace: test
data:
  test-conf: |+
    SESSION_LIFETIME: 3600
    URL: "http://test-server:8080"

执行命令:

kubectl create -f configmap.yaml

若报错:”namespace ‘test’ not found”,则需要先创建namespace:

kubectl create namespace test

2. 通过–from-file

分别指定单个文件和目录,指定目录可以创建一个包含该目录中所有文件的configmap:

kubectl create configmap *** --from-file=/path

将–from-file指定为单个文件就可以从单个文件中创建:

kubectl create configmap *** --from-file=file1

其中,–from-file可以使用多次,比如:

kubectl create configmap *** --from-file=file1 --from-file=file2

3. . 通过key-value字符串创建

kubectl create configmap *** --from-literal=config1=123 --from-literal=config2=234

4. 通过env文件创建

通过环境文件创建:

kubectl create configmap *** --from-env-file=env.txt

其中,env.txt的文件格式为:

config1=***
config2=***

当使用多个–from-env-file从多个数据源创建configmap时,仅最后一个env文件有效。

查看

可以使用以下命令查看创建成功的configmap:

命令说明
kubectl get configmaps查看所有configmap
kubectl get configmaps -n namespace1查看命名空间为namespace1的所有configmap
kubectl describe configmaps configmap1查看configmap1的详细信息
kubectl get configmaps configmap1 -o yaml以yaml文件形式展示configmap详细信息
使用

configmap创建成功之后,如何在pod中使用呢?有以下几种方法:

注意

使用ConfigMap有以下几个限制条件:

  1. ConfigMap必须在pod之前创建
  2. configmap受namespace的限制,只能相同namespace的pod才可以引用

env

通过环境变量获取ConfigMap中的内容。

首先创建configmap:

kubectl create configmap test-config --from-literal=env_model=prd -n test

接下来用作环境变量,创建pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: test
spec:
  containers:
    - name: test-container
      image: test:v0.1
      env:
        - name: TEST-CONF
          valueFrom:
            configMapKeyRef:
              name: test-config
              key: env_model

执行命令创建Pod:

kubectl create -f pod.yaml

创建成功之后,执行命令查看pod的详细信息,可以看到已经将configmap中的配置添加到环境变量:

kubectl describe pod test-pod -n test

同时,也支持多个configmap共同创建环境变量。

volume

通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录,这是我平时用的较多的方式。

接下来使用最开始创建的test-conf为例说明,将configmap挂载到特定目录,并保存为指定文件:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: test
spec:
  containers:
    - name: test-container
      image: test:v0.1
      volumeMounts:
      - name: test-volume
        mountpath: /app/config
  volumes:
    - name: test-volume
    configMap:
      name:test-conf
      items:
      - key: test-conf
        path: config.yaml      

需要注意:In yaml formatting the character “-” implies the start of an array. 不要随意的使用不知道的格式。这可能让你排查一天

项目地址:https://github.com/lWoHvYe/mall-swarm

kubectl 创建对象

$ kubectl create -f ./my-manifest.yaml     #创建资源

$ kubectl create -f ./my1.yaml -f ./my2.yaml    #使用多个文件创建资源

$ kubectl create -f ./dir    #使用目录下的所有清单文件(yaml)来创建资源

$ kubectl create -f https://git.io/vPieo    #使用url创建资源

$ kubectl run nginx –image=nginx    #启动一个nginx实例

$ kubectl explain pods    #获取pod和svc的文档

kubectl 显示和查找资源

以下命令查找资源时可能查不到的原因是需要指定namespace,通过 -n <namespace>指定即可,或者all

$ kubectl get pods –all-namespaces    #列出所有namespace中的pod,也可以是services、deployment等

$ kubectl get pods -o wide    #列出pod并显示详细信息

$ kubectl get deployment my-dep    #列出指定daployment

$ kubectl get pods –include-uninitialized    #列出该namespace中的所有pod,包括未初始化的

使用详细输出来描述命令

$ kubectl describe nodes <my-node IP or name>    #查看node节点信息

$ kubectl describe pods <my-pod>    #查看pod详细信息

$ kubectl get services –sort-by=.metadata.name –all-namespaces    #l列出所有service并按名称排序

根据重启次数排序列出pod

$ kubectl get pods –sort-by=’.status.containerStatuses[0].restartCount’ –all-namespaces

获取所有具有app=cassandra的pod中的version标签

$ kubectl get pods –selector=app=cassandra rc -o jsonpath='{.items[*].metadata.labels.version}’

获取所有节点的ExternalIP

$ kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type==”ExternlIP”)].address}’

kubectl编辑资源

$ kubectl -n codeus edit svc/c    #编辑codeus命名空间下名称为c的service

kubectl Scale 资源

扩展pod下容器数量

$ kubectl scale –replicas=3 rs/foo    #扩展名称为foo的资源到3个,是否使用rs取决于yaml中的编写

例如yaml中kind: Deployment ,则应通过下面方法扩展

$ kubectl scale –replicas=3 deployment/foo

或者直接通过创建资源的yaml文件扩展

$ kubectl scale –replicas=3 -f foo.yaml

根据判断条件扩展

例如条件是:如果mysql的数量是2,则扩展到3

$ kubectl scale –current-replicas=2 –replicas=3 deployment/mysql

同时扩展多个资源

$ kubectl scale –replicas=5 rc/foo rc/bar rc/baz

kubectl 删除资源

$ kubectl delete deployment <name>     #删除指定deployment,此方法还可以删除service等

$ kubectl delete -f xxx.yaml    #通过创建此pod的yaml文件删除pod

kubectl 与运行中的pod交互

$ kubectl -n <namespaces> logs my-podname    #查看pod日志, -f 持续查看

$ kubectl port-forward my-podname 5000:6000    #转发pod中的6000端口到本地的5000端口

$ kubectl exec my-podname — ls /    #在已存在的容器中执行命令

更改宿主机IP地址

k8s的master更换ip后,通信问题出现了问题,我们只需要通过kubeadm init phase命令,重新生成config文件和签名文件就可以了。操作如下: 

一,切换到/etc/kubernetes/manifests, 将etcd.yaml  kube-apiserver.yaml里的ip地址替换为新的ip

/etc/kubernetes/manifests # vim etcd.yaml
/etc/kubernetes/manifests # vim kube-apiserver.yaml

二,生成新的config文件

 /etc/kubernetes# mv admin.conf admin.conf.bak
/etc/kubernetes# kubeadm init phase kubeconfig admin --apiserver-advertise-address <新的ip>

 三,删除老证书,生成新证书

/etc/kubernetes# cd pki
 /etc/kubernetes/pki# mv apiserver.key apiserver.key.bak
/etc/kubernetes/pki# mv apiserver.crt apiserver.crt.bak
 /etc/kubernetes/pki# kubeadm init phase certs apiserver  --apiserver-advertise-address <新的ip>

也可重新生成全部证书
kubeadm certs generate-csr

四,重启docker

/etc/kubernetes# cd ..
/etc/kubernetes# service docker restart
/etc/kubernetes# service kubelet restart

五,将配置文件config输出

/etc/kubernetes#kubectl get nodes --kubeconfig=admin.conf  #  此时已经是通信成功了
/etc/kubernetes#sz admin.conf

 六,将kubeconfig默认配置文件替换为admin.conf,这样就可以直接使用kubectl get nodes

/etc/kubernetes# mv admin.conf ~/.kube/config

admin.conf配置到访问的机器上,就可以通过api访问这台k8s机器了。

Leave a Reply

Your email address will not be published. Required fields are marked *

lWoHvYe 无悔,专一