服务器 > 网络 > 网络协议

Ubuntu下Kubernetes(k8s)集群搭建

71人参与 2024-08-06 网络协议

1.基本概念

1.1master节点

apiserver:集群统一入口,以restful方式,交给etcd存储

scheduler:节点调度,选择worker节点应用部署

controller-manager:处理集群中常规后台任务,一个资源对应一个控制器

etcd:存储系统,用于保存集群相关的数据

1.2worker节点

kubelet:master派到node节点的代表,管理本机容器

kube-proxy:提供网络代理,负载均衡等操作

1.3pod

1.4controller

1.5service

2.环境搭建

安装版本,采用kubeadm搭建,k8s的组件均运行在docker容器中

ubuntukubernetesdocker
22.04 lts1.23.5-005:20.10.14~3-0~ubuntu-jammy

2.1安装指定版本docker

参考docker官网安装教程

#准备工具
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
#add docker’s official gpg key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fssl https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
#set up the repository
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$version_codename")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#查看版本号
sudo apt-cache madison docker-ce
#安装指定版本
sudo apt-get install docker-ce=5:20.10.14~3-0~ubuntu-jammy docker-ce-cli=5:20.10.14~3-0~ubuntu-jammy containerd.io

#docker compose,docker官网安装教程中有,可不安装,不影响运行
#sudo apt-get install containerd.io docker-buildx-plugin docker-compose-plugin

#换仓库地址,写入配置文件
sudo vim /etc/docker/daemon.json
#写入加速器地址
{
    "registry-mirrors": ["https://hub-mirror.c.163.com/"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
#配置docker,kubernetes默认设置cgroup驱动(cgroupdriver)为"systemd",而docker服务的cgroup驱动默认为"cgroupfs",建议将其修改为"systemd",与kubernetes保持一致
#再次修改daemon.json,在其后添加一行"exec-opts":["native.cgroupdriver=systemd"]
sudo vim /etc/docker/daemon.json
{
    "registry-mirrors": ["https://hub-mirror.c.163.com/"],
    "exec-opts":["native.cgroupdriver=systemd"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker

2.2关闭swap分区

sudo vim /etc/fstab
#注释掉 /swapfile 所在行,然后重启计算机即可永久关闭swap

2.3安装kubeadm、kubectl和kubelet

#更新apt源
sudo apt-get update
#使apt支持ssl传输
sudo apt-get install -y apt-transport-https
#下载gpg密钥
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
#添加apt源
sudo apt-add-repository "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
#查看可安装版本
sudo apt-cache madison kubectl
#安装指定版本
sudo apt-get install kubelet=1.23.5-00 kubeadm=1.23.5-00 kubectl=1.23.5-00
#阻止自动更新
sudo apt-mark hold kubelet kubeadm kubectl

2.4配置master节点

#查看集群使用的容器镜像
kubeadm config images list
#拉取所需镜像
sudo kubeadm config images pull --image-repository=registry.aliyuncs.com/google_containers
#初始化
#配置项说明:
#--apiserver-advertise-address k8s 中服务apiserver的部署地址,如果不填写,默认是本机
#--image-repository 拉取的 docker 镜像源,因为初始化的时候kubeadm会去拉 k8s 的很多组件来进行部署,所以需要指定国内镜像源,下不然会拉取不到镜像
#--pod-network-cidr k8s采用的节点网络,该参数指定了为pod节点分配的虚拟ip网段
#--kubernetes-version: 这个是用来指定你要部署的 k8s 版本的,一般不用填,不过如果初始化过程中出现了因为版本不对导致的安装错误的话,可以用这个参数手动指定
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.23.5 --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=192.168.121.130
#初始化
mkdir -p $home/.kube
  sudo cp -i /etc/kubernetes/admin.conf $home/.kube/config
  sudo chown $(id -u):$(id -g) $home/.kube/config
#查看集群节点
kubectl get nodes
#查看集群状态
kubectl get cs
#以上步骤安装完后,机器搭建起来了,但状态还是notready状态,master机器需要安装网络插件calico
#下面是一个网上别人整理好的资源清单,之间运行k8s会在docker中拉起相应的服务
kubectl apply -f https://docs.projectcalico.org/v3.21/manifests/calico.yaml
#再次查看集群节点,状态变为ready
kubectl get nodes
#查看集群状态
kubectl get cs

输出信息如下,执行其中的mkdir,cp等命令,最后的输出kubeadm join命令用于worker节点加入集群

your kubernetes control-plane has initialized successfully!

to start using your cluster, you need to run the following as a regular user:

  mkdir -p $home/.kube
  sudo cp -i /etc/kubernetes/admin.conf $home/.kube/config
  sudo chown $(id -u):$(id -g) $home/.kube/config

alternatively, if you are the root user, you can run:

  export kubeconfig=/etc/kubernetes/admin.conf

you should now deploy a pod network to the cluster.
run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.121.130:6443 --token 1uwxx8.zkr71sdz5uu7z2t1 \
	--discovery-token-ca-cert-hash sha256:5d0df7efc1d8895ec4c93e7d926738d4311fd36b6f14b18dffbaf4e07d66213d

2.5配置worker节点

#更新apt源
sudo apt-get update
#使apt支持ssl传输
sudo apt-get install -y apt-transport-https
#下载gpg密钥
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
#添加apt源
sudo apt-add-repository "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main"
#查看可安装版本
sudo apt-cache madison kubectl
#安装指定版本
sudo apt-get install kubelet=1.23.5-00 kubeadm=1.23.5-00 kubectl=1.23.5-00
#阻止自动更新
sudo apt-mark hold kubelet kubeadm kubectl
#加入集群
sudo kubeadm join 192.168.121.130:6443 --token 1uwxx8.zkr71sdz5uu7z2t1 \
	--discovery-token-ca-cert-hash sha256:5d0df7efc1d8895ec4c93e7d926738d4311fd36b6f14b18dffbaf4e07d66213d
#查看token和hash
kubeadm token list
kubeadm token inspect <token名称>
#新建token
kubeadm token create --print-join-command
#部署完后在master节点查看
kubectl get nodes
#输出如下:
#name                  status   roles                  age    version
#lzy-virtual-machine   ready    control-plane,master   35m    v1.23.5
#worker-node1          ready    <none>                 2m7s   v1.23.5

3.基本操作

3.1kubectl使用

环境准备,将主节点的.kube/config文件复制到worker节点中

#使用命令验证
kubectl get nodes
#查看命令
kubectl --help
#查看生成的标签
kubectl get node --show-labels
#给节点node2打上标签env=prod
kubectl label node node2 env=prod

3.2集群资源清单

用于资源编排

yaml文件组成部分,由控制器定义和被控制对象组成,示例:

#控制器定义
apiversion: apps/v1
kind: deployment #资源类型
metadata:
  name: nginx-deployment
  namespace: default
spec:
  replicas: 1 #副本数量
  selector:
    matchlabels:
      app: nginx
#被控制对象
  template: #pod模板
    metadata: #pod元数据
      labels:
        app: nginx
    spec:
      containers: #容器配置
      - name: nginx #容器名称
        image: nginx:1.18 #容器镜像
        imagepullpolicy: ifnotpresent #获取镜像的策略
        ports: #pod的重启策略
        - containerport: 80 #容器需要监听的端口号 
      restartpolicy: always #pod的重启策略

常用字段说明

参数名数据类型说明
apiversionstring指k8s api的版本,可以用kubectl api-versions命令查看,一般为v1
kindstring指yaml文件定义的资源类型和角色,比如pod
metadataobject元数据对象
metadata.namestring元数据对象的名字,这里由我们编写
metadata.namespacestring元数据对象的命名空间
specobject详细定义对象
spec.containers[]list容器列表
spec.containers[].namestring容器名
spec.containers[].namestring镜像名称
spec.containers[].imagepullpolicystring容器镜像拉取策略,always、never、ifnotpresent
#应用资源清单文件
kubectl apply -f filename.yaml
#使用kubectl create命令生成yaml文件
kubectl create deployment test --image=nginx:1.18 -o yaml --dry-run > my1.yaml
#使用kubectl get命令导出yaml文件
#旧版本为kubectl get deploy nginx-app -o=yaml --export > my2.yaml
kubectl get deploy nginx-app -o=yaml > my2.yaml

3.3namespace

#查看命名空间
kubectl get namespace
#以下为输出
#name              status   age
#default           active   2d17h
#kube-node-lease   active   2d17h
#kube-public       active   2d17h
#kube-system       active   2d17h
#其中default为用户创建pod的默认命名空间
#kube-public 为所有用户均可访问的命名空间,包括未认证用户
#kube-node-lease 为kubernetes集群节点租约状态,v1.13加入
#kube-system kubernetes集群使用的命名空间

#创建命名空间
kubectl create namespace test

#删除命名空间
kubectl delete namespace test

3.4pod

一个pod中的多个容器可以共享存储和网络,可以看作一个逻辑的主机。共享的如namespace,cgroups 或者其他的隔离资源。

pod实现共享网络机制:pod中首先自动创建pause容器(根容器),再创建业务容器,并将业务容器加入根容器,让所有业务容器在同一个namespace中,实现网络共享

pod实现共享存储机制:引入数据卷概念volumn,实现共享存储

查看pod

#查看pod
kubectl get pods
#或
kubectl get pods --namespace default
#进入pod
kubectl exec -it [podname] bash

创建pod,以部署nginx应用为例

#拉取镜像
sudo docker pull nginx:1.18

资源清单nginx.yaml

apiversion: v1
kind: pod
metadata:
  name: pod1
  namespace: default
spec:
  containers:
  - name: nginx-pod
    image: nginx:1.18
    imagepullpolicy: ifnotpresent
    ports:
    - name: nginxport
      containerport: 80

创建pod,创建pod时scheduler会使用调度算法将pod分配给相应的node

#应用资源清单文件
kubectl apply -f nginx.yaml
#查看是否成功创建
kubectl get pods -o wide
#输出为
#name   ready   status    restarts   age     ip                node           nominated node   readiness gates
#pod1   1/1     running   0          3m34s   192.168.180.193   worker-node1   <none>           <none>
#可通过192.168.180.193进行访问
#删除pod
kubectl delete pods pod1 -n default

3.5controller控制器

在集群上管理和运行容器的对象

当pod出现问题时,会把pod重新拉起,以达到用户的期望状态

常见pod控制器

控制器名称作用
deployment声明式更新控制器,用于发布无状态应用
replicaset副本集控制器,用于对pod进行副本规模扩大或裁剪
statefulset有状态副本集,用于发布有状态应用
daemonset在k8s集群每一个node上运行一个副本,用于发布监控或日志收集类等应用
job运行一次性作业任务
cronjob运行周期性作业任务
#创建deployment控制器类型应用
kubectl apply -f deployment.yaml
#查看
kubectl get deployment
#删除,使用kubectl delete pods直接删除pod会被重新拉起
kubectl delete deployment nginx-app
#弹性伸缩
kubectl scale deployment nginx-deployment --replicas==2
3.5.1部署无状态应用(deployment)
kubectl apply -f deployment.yaml
kubectl expose deployment nginx-deployment --type=nodeport --target-port=80 --port=8000

示例资源清单deployment.yaml

#控制器定义
apiversion: apps/v1
kind: deployment #资源类型
metadata:
  name: nginx-deployment
  namespace: default
spec:
  replicas: 1 #副本数量
  selector:
    matchlabels:
      app: nginx
#被控制对象
  template: #pod模板
    metadata: #pod元数据
      labels:
        app: nginx
    spec:
      containers: #容器配置
      - name: nginx #容器名称
        image: nginx:1.18 #容器镜像
        imagepullpolicy: ifnotpresent #获取镜像的策略
        ports: #pod的重启策略
        - containerport: 80 #容器需要监听的端口号 
      restartpolicy: always #pod的重启策略
3.5.2部署有状态应用(statefulset)

示例资源清单statefulset.yaml

#控制器定义
apiversion: apps/v1
kind: statefulset #资源类型
metadata:
  name: nginx-statefulset
  namespace: default
spec:
  servicename: nginx
  replicas: 2 #副本数量
  selector:
    matchlabels:
      app: nginx
#被控制对象
  template: #pod模板
    metadata: #pod元数据
      labels:
        app: nginx
    spec:
      containers: #容器配置
      - name: nginx #容器名称
        image: nginx:1.18 #容器镜像
        imagepullpolicy: ifnotpresent #获取镜像的策略
        ports: #pod的重启策略
        - containerport: 80 #容器需要监听的端口号 
      restartpolicy: always #pod的重启策略

service资源清单service.yaml

apiversion: v1
kind: service #资源类型
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterip: none
  selector:
    app: nginx #对应statefulset.yaml中的spec.template.metadata.labels.app

3.6service

作用:

service类型:

#创建应用
kubectl apply -f deployment.yaml
#创建service
#target-port指pod的端口,port指外部访问端口
kubectl expose deployment nginx-app --type=clusterip --target-port=80 --port=8000
#查看
kubectl get service
#删除service
kubectl delete service nginx-app
#创建nodeport类型service,使外网也能访问,在每个node上分配一个端口作为外部访问入口
kubectl expose deployment nginx-app --type=nodeport --target-port=80 --port=8000
#kubectl get service查看service,输出如下
#name         type        cluster-ip       external-ip   port(s)          age
#kubernetes   clusterip   10.96.0.1        <none>        443/tcp          2d22h
#nginx-app    nodeport    10.111.139.105   <none>        8000:31062/tcp   2s
#外网可通过任意节点的31062端口访问nginx

3.7secret

作用:加密数据存在etcd里,让pod容器以挂载volume方式进行访问

kubectl apply -f secret.yaml
3.7.1secret.yaml(数据要自己base64加密)
apiversion: v1
kind: secret
metadata: 
  name: mysecret
type: opaque
data:
  username: bhp5
  password: mtizndu2

以变量形式挂载到pod

kubectl apply -f pod.yaml
kubectl exec -it mypod bash
echo $secret_username

pod.yaml

apiversion: v1
kind: pod
metadata: 
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    imagepullpolicy: ifnotpresent
    ports:
    - containerport: 80
    env:
      - name: secret_username
        valuefrom:
          secretkeyref:
            name: mysecret
            key: username
      - name: secret_password
        valuefrom:
          secretkeyref:
            name: mysecret
            key: password
3.7.2以volume的形式挂载到pod中
kubectl apply -f pod.yaml
kubectl exec -it mypod bash
cd /etc/foo
ls
cat username
cat password

pod.yaml

apiversion: v1
kind: pod
metadata: 
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    imagepullpolicy: ifnotpresent
    ports:
    - containerport: 80
    volumemounts: #挂载位置
    - name: foo
      mountpath: "/etc/foo"
      readonly: true
  volumes: #数据来源
  - name: foo
    secret:
      secretname: mysecret

3.8configmap

作用:存储不加密数据到etcd,让pod以变量或者volume挂载到容器中

3.8.1以变量形式挂载到pod
kubectl apply -f configmap.yaml 
kubectl apply -f pod.yaml
kubectl exec -it mypod bash
echo $info

configmap.yaml

apiversion: v1
kind: configmap
metadata: 
  name: my-config
data:
  config.info: info

pod.yaml

apiversion: v1
kind: pod
metadata: 
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    imagepullpolicy: ifnotpresent
    ports:
    - containerport: 80
    env:
      - name: info
        valuefrom:
          configmapkeyref:
            name: my-config
            key: config.info
3.8.2以volume形式挂载到pod中
#创建configmap
kubectl create configmap redis-config --from-file=redis.properties
#查看
kubectl get cm
kubectl apply -f pod.yaml
kubectl exec -it mypod bash
cat /etc/config/redis.properties

redis.properties

redis.host=127.0.0.1
redis.port=6379
redis.password=123456

pod.yaml

apiversion: v1
kind: pod
metadata: 
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    imagepullpolicy: ifnotpresent
    ports:
    - containerport: 80
    volumemounts: #挂载位置
    - name: config-volume
      mountpath: "/etc/config"
      readonly: true
  volumes: #数据来源
  - name: config-volume
    configmap:
      name: redis-config

附录:yaml具体解释

# yaml格式的pod定义文件完整内容:
apiversion: v1       #必选,版本号,例如v1
kind: pod       #必选,pod
metadata:       #必选,元数据
  name: string       #必选,pod名称
  namespace: string    #必选,pod所属的命名空间
  labels:      #自定义标签
    - name: string     #自定义标签名字
  annotations:       #自定义注释列表
    - name: string
spec:         #必选,pod中容器的详细定义
  containers:      #必选,pod中容器列表
  - name: string     #必选,容器名称
    image: string    #必选,容器的镜像名称
    imagepullpolicy: [always | never | ifnotpresent] #获取镜像的策略 alawys表示下载镜像 ifnotpresent表示优先使用本地镜像,否则下载镜像,nerver表示仅使用本地镜像
    command: [string]    #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]     #容器的启动命令参数列表
    workingdir: string     #容器的工作目录
    volumemounts:    #挂载到容器内部的存储卷配置
    - name: string     #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountpath: string    #存储卷在容器内mount的绝对路径,应少于512字符
      readonly: boolean    #是否为只读模式
    ports:       #需要暴露的端口库号列表
    - name: string     #端口号名称
      containerport: int   #容器需要监听的端口号
      hostport: int    #容器所在主机需要监听的端口号,默认与container相同
      protocol: string     #端口协议,支持tcp和udp,默认tcp
    env:       #容器运行前需设置的环境变量列表
    - name: string     #环境变量名称
      value: string    #环境变量的值
    resources:       #资源限制和请求的设置
      limits:      #资源限制的设置
        cpu: string    #cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string     #内存限制,单位可以为mib/gib,将用于docker run --memory参数
      requests:      #资源请求的设置
        cpu: string    #cpu请求,容器启动的初始可用数量
        memory: string     #内存清楚,容器启动的初始可用数量
    livenessprobe:     #对pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpget和tcpsocket,对一个容器只需设置其中一种方法即可
      exec:      #对pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpget:       #对pod内个容器健康检查方法设置为httpget,需要制定path、port
        path: string
        port: number
        host: string
        scheme: string
        httpheaders:
        - name: string
          value: string
      tcpsocket:     #对pod内个容器健康检查方式设置为tcpsocket方式
         port: number
       initialdelayseconds: 0  #容器启动完成后首次探测的时间,单位为秒
       timeoutseconds: 0   #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodseconds: 0    #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successthreshold: 0
       failurethreshold: 0
       securitycontext:
         privileged:false
    restartpolicy: #[always | never | onfailure]#pod的重启策略,always表示一旦不管以何种方式终止运行,kubelet都将重启,onfailure表示只有pod以非0退出码退出才重启,nerver表示不再重启该pod
    nodeselector: obeject  #设置nodeselector表示将该pod调度到包含这个label的node上,以key:value的格式指定
    imagepullsecrets:    #pull镜像时使用的secret名称,以key:secretkey格式指定
    - name: string
    hostnetwork:false      #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
    volumes:       #在该pod上定义共享存储卷列表
    - name: string     #共享存储卷名称 (volumes类型有很多种)
      emptydir: {}     #类型为emtydir的存储卷,与pod同生命周期的一个临时目录。为空值
      hostpath: string     #类型为hostpath的存储卷,表示挂载pod所在宿主机的目录
        path: string     #pod所在宿主机的目录,将被用于同期中mount的目录
      secret:      #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
        scretname: string  
        items:     
        - key: string
          path: string
      configmap:     #类型为configmap的存储卷,挂载预定义的configmap对象到容器内部
        name: string
        items:
        - key: string
(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

【Kubernetes】神乎其技的K8s到底是什么,为什么被越来越多人使用

08-06

微服务与服务网格技术的性能优化:实现低延迟与高吞吐量

08-06

计算机视觉目标检测性能指标

08-06

【音视频 | RTSP】RTSP协议详解 及 抓包例子解析(详细而不赘述)

08-06

腾讯云TStor存储一体机在大模型场景下的业务实践

08-06

腾讯云海外版对象储存服务COS使用教程(图文教程)

08-06

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论