kubernetes笔记

1.组件

  • Scheduler: kube-scheduler 调度器 挑选合适的节点

  • Controller Manager:一个资源对应一个控制器,通过 API Server 监控整个集群的状态(去数据库查询),一旦有pod死亡会通知schedluer选择合适的节点重启,相当于古代的巡抚

  • Cloud controller Manager:云平台上的kube-controller

  • API Server: kube-apiserver,集群的统一入口,各组件协调者,以RESTFUL API提供接口服务,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给etcd存储。

  • Etcd:分布式键值存储系统,用于保存集群状态与元数据信息

  • kubelet: 可以理解为Master在工作节点上的Agent,管理本机运行容器的生命周期,比如创建容器,Pod挂载数据卷,下载secret,获取容器的节点状态等工作。kubelet将每一个Pod转换成一组容器。

  • kube-proxy: 外界访问集群的代理,一般外部会有keeplivad做VIp 然后在负载均衡到proxy

  • POD:用户划分容器的最小单位,一个POD可以存在多个容器。

  • CNI:集群通讯

  • cAdvisor:监控pod 采集数据上传给kubelet kubelet会传给apiserver 然后存储在etcd

image-20230312120445451

image-20230312121210807

组件使用的端口号

image-20230313112022956

2.安装的方式

yum安装:

    优点:

        安装,配置很简单,适合新手学习。

    缺点:

        版本较低,目前仅支持K8S 1.5.2版本,很多功能不支持。

kind安装:

    kind让你能够在本地计算机上运行Kubernetes。 kind要求你安装并配置好Docker。

    推荐阅读:

        https://kind.sigs.k8s.io/docs/user/quick-start/

minikube部署:

    minikube是一个工具, 能让你在本地运行Kubernetes。 

    minikube在你本地的个人计算机(包括 Windows、macOS 和 Linux PC)运行一个单节点的Kubernetes集群,以便你来尝试 Kubernetes 或者开展每天的开发工作。因此很适合开发人员体验K8S。

    推荐阅读:

        https://minikube.sigs.k8s.io/docs/start/

kubeadm:

    你可以使用kubeadm工具来创建和管理Kubernetes集群,适合在生产环境部署。

    该工具能够执行必要的动作并用一种用户友好的方式启动一个可用的、安全的集群。

    推荐阅读:

        https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/

        https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

        https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/



二进制部署:

    安装步骤比较繁琐,但可以更加了解细节。适合运维人员生产环境中使用。

源码编译安装:

    难度最大,请做好各种故障排查的心理准备。其实这样一点对于K8S二次开发的人员应该不是很难。

kubeadm部署

(1)虚拟机操作系统环境准备

参考链接:

    https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/


(2)关闭swap分区

    1)临时关闭

swapoff -a && sysctl -w vm.swappiness=0

    2)基于配置文件关闭

sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab


(3)确保各个节点MAC地址或product_uuid唯一

ifconfig  eth0  | grep ether | awk '{print $2}'

cat /sys/class/dmi/id/product_uuid 

    温馨提示:

        一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 

        Kubernetes使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装失败。

(4)检查网络节点是否互通

简而言之,就是检查你的k8s集群各节点是否互通,可以使用ping命令来测试。


(5)允许iptable检查桥接流量

cat <<EOF | tee /etc/modules-load.d/k8s.conf

br_netfilter

EOF


cat <<EOF | tee /etc/sysctl.d/k8s.conf

net.bridge.bridge-nf-call-ip6tables = 1

net.bridge.bridge-nf-call-iptables = 1

EOF

sysctl --system


(6)检查端口是否被占用

参考链接: https://kubernetes.io/zh/docs/reference/ports-and-protocols/


(7)检查docker的环境

参考链接:

    https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.15.md#unchanged
  

    1)配置docker源

curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

curl -o /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo

sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

yum list docker-ce --showduplicates


    2)安装指定的docker版本

yum -y install docker-ce-18.09.9 docker-ce-cli-18.09.9

yum -y install bash-completion

source /usr/share/bash-completion/bash_completion


    3)打包软件包分发到其他节点部署docker(此步骤可跳过)

mkdir docker-rpm-18-09 && find /var/cache/yum -name "*.rpm" | xargs mv -t docker-rpm-18-09/
​

    4)配置docker优化

mkdir -pv /etc/docker && cat <<EOF | sudo tee /etc/docker/daemon.json

{

  "insecure-registries": ["192.168.200.136:5000"],

  "registry-mirrors": ["https://tuv7rqqq.mirror.aliyuncs.com"],

  "exec-opts": ["native.cgroupdriver=systemd"]

}

EOF

    

    5)配置docker开机自启动

systemctl enable --now docker && systemctl status docker



(8)禁用防火墙

systemctl disable --now firewalld



(9)禁用selinux
getenforce 0

sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config 

grep ^SELINUX= /etc/selinux/config



(10)配置host解析

cat >> /etc/hosts <<'EOF'
192.168.200.136       master
192.168.200.137       node1
192.168.200.138       node2
EOF

cat /etc/hosts

(11)在master节点启用docker registry的私有仓库

docker run -dp 5000:5000 --restart always --name oldboyedu-registry registry:2


安装k8s

(1)配置软件源

cat  > /etc/yum.repos.d/kubernetes.repo <<EOF

[kubernetes]

name=Kubernetes

baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/

enabled=1

gpgcheck=0

repo_gpgcheck=0

EOF

(2)安装kubeadm,kubelet,kubectl软件包

yum -y install kubeadm-1.15.12-0 kubelet-1.15.12-0 kubectl-1.15.12-0 


(3)查看kubeadm的版本(将来你要安装的K8S时请所有组件版本均保持一致!)

yum -y list kubeadm --showduplicates | sort -r


(4)启动kubelet服务(若服务启动失败时正常现象,其会自动重启,因为缺失配置文件,初始化集群后恢复!此步骤可跳过!)

systemctl enable --now kubelet && systemctl status kubelet



参考链接:

    https://kubernetes.io/zh/docs/tasks/tools/install-kubectl-linux/



master初始化
kubeadm init --kubernetes-version=v1.15.12 --image-repository registry.aliyuncs.com/google_containers  --pod-network-cidr=10.244.0.0/16 --service-cidr=10.254.0.0/16
master按照要求
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
node加入节点
kubeadm init --kubernetes-version=v1.15.12 --image-repository registry.aliyuncs.com/google_containers  --pod-network-cidr=10.244.0.0/16 --service-cidr=10.254.0.0/16






master配置网络
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml

验证flannel插件是否部署成功:
kubectl get nodes
kubectl get pods -A -o wide | grep  flannel

配置tab
echo "source <(kubectl completion bash)" >> ~/.bashrc && source ~/.bashrc 

补充:
<<EOF    输入重定向
cat > xxx << EOF  输入重定向到xxx(覆盖模式) 直到遇到EOF停止
使用kubeadm初始化集群时,可能会出现如下的输出信息:

[init] 

    使用初始化的K8S版本。

    

[preflight] 

    主要是做安装K8S集群的前置工作,比如下载镜像,这个时间取决于你的网速。

​

[certs] 

    生成证书文件,默认存储在"/etc/kubernetes/pki"目录哟。

​

[kubeconfig]

    生成K8S集群的默认配置文件,默认存储在"/etc/kubernetes"目录哟。

​

[kubelet-start] 

    启动kubelet,

    环境变量默认写入:"/var/lib/kubelet/kubeadm-flags.env"

    配置文件默认写入:"/var/lib/kubelet/config.yaml"

​

[control-plane]

    使用静态的目录,默认的资源清单存放在:"/etc/kubernetes/manifests"。

    此过程会创建静态Pod,包括"kube-apiserver","kube-controller-manager"和"kube-scheduler"

​

[etcd] 

    创建etcd的静态Pod,默认的资源清单存放在:""/etc/kubernetes/manifests"

    

[wait-control-plane] 

    等待kubelet从资源清单目录"/etc/kubernetes/manifests"启动静态Pod。

​

[apiclient]

    等待所有的master组件正常运行。

    

[upload-config] 

    创建名为"kubeadm-config"的ConfigMap在"kube-system"名称空间中。

    

[kubelet] 

    创建名为"kubelet-config-1.22"的ConfigMap在"kube-system"名称空间中,其中包含集群中kubelet的配置

​

[upload-certs] 

    跳过此节点,详情请参考”--upload-certs"
  

[mark-control-plane]

    标记控制面板,包括打标签和污点,目的是为了标记master节点。

 

[bootstrap-token] 

    创建token口令,例如:"kbkgsa.fc97518diw8bdqid"。

    如下图所示,这个口令将来在加入集群节点时很有用,而且对于RBAC控制也很有用处哟。


[kubelet-finalize] 

    更新kubelet的证书文件信息


[addons] 

    添加附加组件,例如:"CoreDNS"和"kube-proxy”

    

3.pod

Pod是Kubernetes集群中最小部署单元,一个Pod由一个容器或多个容器组成,这些容器可以共享网络,存储等资源等。


Pod有以下特点:

    (1)一个Pod可以理解成一个应用实例,提供服务;

    (2)Pod中容器始终部署在同一个Node上;

    (3)Pod中容器共享网络,存储资源;

    (4)Kubernetes集群是直接管理Pod,而不是容器;
    
    
pod共享网络空间 不实行网络隔离

运行一个pod

(1)编写资源清单

cat > 01-pod-nginx.yaml <<'EOF'
kind: Pod                       # 部署的资源类型
apiVersion: v1                  # API的版本号
metadata:                       # 元数据信息
  name: oldboyedu-linux81-web   # 资源的名称
spec:                           # 自定义Pod资源的配置                                   
  containers:                   #此处分割开 spec之上为资源概述,之下为里面运行的容器概述              
  - name: linux81-web           # 定义容器的名称
    image: nginx:1.18           # 定义容器基于哪个镜像启动
EOF 





创建资源

kubectl create -f 01-pod-nginx.yaml 

查看pod资源

kubectl get pods
kubectl get pods -o wide  ##查看的更详细 带IP地址

字段说明

相关字段说明:

    NAME

        代表的是资源的名称。

    READY   

        代表资源是否就绪。比如 0/1 ,表示一个Pod内有一个容器,而且这个容器还未运行成功。

    STATUS    

        代表容器的运行状态。

    RESTARTS   

        代表Pod重启次数,即容器被创建的次数。

    AGE     

        代表Pod资源运行的时间。

    IP            

        代表Pod的IP地址。

    NODE

        代表Pod被调度到哪个节点。

    其他: 

        "NOMINATED NODE和"READINESS GATES"暂时先忽略哈。

pod网络空间共享

image-20230314083816422

Pod:
基础容器: pause,提供网络空间。    只能在docker命令下看到
容器1: nginx   ---> COMMAND
容器2: filebeat ---> COMMAND  XXXX 

4.常用命令

#查看K8S支持的资源类型。
kubectl api-resources

get查询

kubectl get po,no         
kubectl get pods -o wide   #额外显示调度节点和IP

-o 指定输出的格式

-o yaml

-o json


kubectl get pods -o yaml    # 查看Pod资源创建时的yaml文件,若用户为定义,此处会有默认字段 
kubectl get pods --show-labels    #查看票钱

delete删除

kubectl delect -f  02-pod-nginx-alpine.yaml #基于文件删除资源

kubectl delete pods  nginx1  #基于pod名删除

kubectl delete pod --all     ##删除所有的pod

create创建

kubect create -f xxxx.yaml

kubectl apply -f xxx.yaml   #更新+创建

explain命令帮助查看

Kubectl explain pod.metadata




string    字符类型   xx:xx

object   下一级字段 需要缩进
metadata:
  name: oldboyedu-linux81-web   

[]object   数组,下一级带-

[]string     多组数组值

agrs:
- "tail"
-  "-f"
-  "/etc/passwd"


[string]string
key:valuse

metadata:
  name: xxx
  labels:
    class: xx
    school: xxxxx

command和args

command相当于docker的entrypoint 其后均参数
args相当于CMD

image-20230313220402485

多个command只生效第一个

image-20230313221018582

image-20230313222019697

两个的时候后面会覆盖前面的

labels标签

  • 声明式
metadata:
  name: oldboyedu-linux81-web
  labels:
    apps: web
    class: linux81
    school: oldboyedu
    address: shahe
  • 响应式
语法:
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] [options]


kubectl label pods goose shcool=oldbouedu class= linux81
kubectl label -f nginx.yaml address=shahe                                    ##改pod由配置文件nginx.yaml启动
kubectl label --overwrite pod goose adddress=hsgoose                         ##覆盖标签、没有创建
kubectl label pods goose address-                                            ##删除标签

cp文件复制

kubectl cp goose.yaml goose:/           将goose.yaml复制到其第一个容器内
kubectl cp goose.yaml goose:/  -c nginx-v1
kubectl cp goose:/etc -c nginx-v1 ./

故障排查命令

describe

 kubectl describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME) [options]


kubectl describe pod goose  
kubectl describe -f 01-pod-nginx.yaml  查看"01-pod-nginx.yaml"资源清单的资源详细信息。(了解即可)  
kubectl describe pod  -l  apps=myweb   查看标签名称为"apps=myweb"的所有po资源详细信息。




几个字段

CrashLoopBackOff  崩溃不断重启
terminate  终止

logs(查看内部容器信息)

  kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER] [options]
-f: 动态读取
-c: 指定容器名字(只有一个容器不用指定,多余不指定报错)
--timestamps  查看时间戳
--since 查看最近几分钟的
kubectl logs -f goose -c nginx-v1
kubectl logs -f goose -c nginx-v1 --timestamps --since=10m

exec

kubectl exec (POD | TYPE/NAME) [-c CONTAINER] [flags] [options]  -- COMMAND [args...] 

kubectl exec goose -- cat /etc/hosts
kubectl exec pod goose --cat /etc/hosts
kubectl exec pod goose -c nginx-v1 -- hostname -i

进入排错
kubectl exec pod goose -c nginx-v1 -it -- sh

5.资源限制

kind: Pod
apiVersion: v1
metadata:
  name: hsgoose1
  labels:
     apps: myweb
spec:
  containers:
  - name: web01
    image: nginx:1.18
    # 配置容器的资源限制
    resources:
       # 设置资源的上线
       limits:
          # 配置内存限制
          memory: "200Mi"
          # 配置CPU的显示,CPU的换算公式: 1core = 1000m 
          cpu: "500m"
       # 配置容器期望的资源,如果所有节点不符合期望的资源,则无法完成调度
       requests:
          memory: "100Mi"
          cpu: "500m"
          
limits 和requests
limits:最大资源的限制  其中 1core = 1000m
requests: 期望资源,如果调度主机达不到就换一个,所有主机都达不到就会启动失败

6.镜像下载策略

指定调度节点

字段;nodeName     <string>
spec:
  # 将Pod调度到指定到节点名称
  # 注意,节点名称不能乱写,必须是在"kubectl get nodes"指令中存在.
  nodeName: node1
  containers:
  - name: linux001

宿主机共享网络空间

(直接和主机进行连同,共用端口,注意是否端口冲突,)

字段hostNetwork  <boolean>
    Host networking requested for this pod. Use the host's network namespace.
     If this option is set, the ports that will be used must be specified.
     Default to false.

spec:
  # 将Pod调度到指定到节点名称
  # 注意,节点名称不能乱写,必须是在"kubectl get nodes"指令中存在.
  nodeName: node1
  hostNetwork: true
  containers:
  - name: linux001

镜像下载策略

spec:
  # 将Pod调度到指定到节点名称
  # 注意,节点名称不能乱写,必须是在"kubectl get nodes"指令中存在.
  nodeName: k8s202.oldboyedu.com
  containers:
  - name: linux80-web
    image: k8s201.oldboyedu.com:5000/nginx:1.18
    # 指定镜像的下载策略,其值为:  Always, Never, IfNotPresent
    # Always:
    #    总是去拉取最新的镜像,这是默认值.
    #    如果本地镜像存在同名称的tag,其会取出该镜像的RepoDigests(镜像摘要)和远程仓库的RepoDigests进行比较
    #    若比较结果相同,则直接使用本地缓存镜像,若比较结果不同,则会拉取远程仓库最新的镜像
    # Never:
    #    如果本地有镜像,则尝试启动容器;
    #    如果本地没有镜像,则永远不会去拉取尝试镜像。
    # IfNotPresent:
    #    如果本地有镜像,则尝试启动容器,并不会去拉取镜像。
    #    如果本地没有镜像,则会去拉取镜像。
    imagePullPolicy: Always
    stdin: true                            #标准输入,卡住容器
posted @ 2023-03-14 16:17  hsgoose  阅读(73)  评论(0)    收藏  举报