服务器-Kubernetes (K8S)单机部署实战 -- 001
  M3qYdfITNP06 2024年02月19日 23 0

     本篇博文是 centos 7 系统安装 kubernetes 单机 master 节点操作。

一: 查看 服务器 配置信息

      1. 执行命令查看服务器cpu信息。安装 kubernetes 服务,cpu核心数必须大于2,内存大于2G。

lscpu

      2.  修改服务器设置信息,避免安装出现问题。

        a.  临时关闭swap,防止 执行 kubeadm 命令爆错。

swapoff -a

       b. 临时关闭 selinux,减少不必要的配置。

setenforce 0

      c. 关闭防火墙 

systemctl stop firewalld
systemctl disable firewalld

      d. 设置网桥信息

cat << EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

     e. 修改 主机名为 master 

hostnamectl set-hostname master

      f. 修改 hosts 文件,设置 master 主机名称和本机IP 映射关系

10.0.0.206 master

 

二: 安装并配置 docker

   1. 安装必须工具

yum install -y yum-utils device-mapper-persistent-data lvm2

  2. 添加 阿里云 yum 仓库 repo

yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

  3. 安装 docker 

yum -y install docker-ce

  4. 修改 docker 的   /etc/docker/daemon.json 文件。如果文件不存在,则创建新的。

      a. 设置 阿里云国内 docker 源

      b.  设置 cgroupdriver 为 systemd

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xcjha0pw.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

   5. 修改完后,使用新配置 重启 docker 服务。

sudo systemctl daemon-reload
sudo systemctl restart docker

   6. 设置 docker 服务开机自启动

systemctl enable docker

   7. 生成 containerd 配置信息,并修改 两处相关配置。

      # 生成 containerd 的默认配置文件
      containerd config default > /etc/containerd/config.toml

     a. 修改1 修改 sandbox_image 镜像配置,改为阿里镜像。

           # 查看 sandbox 的默认镜像仓库在文件中的第几行
           cat /etc/containerd/config.toml | grep -n "sandbox_image"

          # 使用 vim 编辑器 定位到 sandbox_image,将 仓库地址修改成 阿里镜像
            vim /etc/containerd/config.toml

            sandbox_image = " registry.aliyuncs.com/google_containers/pause:3.6"

       b. 修改2  注释掉 cri 插件,否则 kubelet 无法启动。

sed -i -r '/cri/s/(.*)/#\1/' /etc/containerd/config.toml
systemctl restart containerd

      # 重启 containerd 服务
    systemctl daemon-reload
    systemctl restart containerd

 

 

三:kubernetes 安装操作步骤

      1. 配置 kubernetes 下载源。使用国内阿里云 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

     2. 安装 kubernetes 服务的相关应用 kubectl, kubeadm, kubectl 

       kubelet:  运行在 cluster, 负责启动 pod,并管理容器。

       kubeadm:  kubernetes 快速构建工具,用于初始化 cluster。

       kubectl: kubernetes 命令工具。进行服务的部署和管理。

yum install -y --nogpgcheck kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 

     3. 查看安装结果

kubelet --version
kubectl version
kubeadm version

    4. 启动 kubelet 服务

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

    5.  生成 kubernetes  初始化配置文件 init-config.yaml, 并根据实际情况修改 3 处

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 10.0.0.206   //修改1 master节点IP地址 可cat /etc/hosts 看到
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  imagePullPolicy: IfNotPresent
  name: master   //修改2 master节点node的名称
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers   //修改3 修改为阿里云地址
kind: ClusterConfiguration
kubernetesVersion: 1.28.0
networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/12 scheduler: {}

   6.  下载 kubernetes 相关镜像

   注意执行目录在  init-config.yaml 文件目录

kubeadm config images pull --config=init-config.yaml

  当镜像拉取失败,通过命令获取所有需要的镜像,然后一个个拉取

kubeadm config images list --config init-config.yaml

结果如下(不同版本有差别):

registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.0
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.28.0
registry.aliyuncs.com/google_containers/kube-scheduler:v1.28.0
registry.aliyuncs.com/google_containers/kube-proxy:v1.28.0
registry.aliyuncs.com/google_containers/pause:3.9
registry.aliyuncs.com/google_containers/etcd:3.5.9-0
registry.aliyuncs.com/google_containers/coredns:v1.10.1

   7.  运行 kubeadm 初始化操作,进行master 节点安装

kubeadm init --apiserver-advertise-address=10.0.0.206 --apiserver-bind-port=6443 --pod-network-cidr=10.244.0.0/16  --service-cidr=10.96.0.0/12 --kubernetes-version=1.28.2 --image-repository registry.aliyuncs.com/google_containers

   8.  如果安装失败,重置集群初始化,然后再执行 7 步骤。

kubeadm reset

   9.  在 master 节点服务执行如下命令,进行 管理员信息配置,方便获取 token 信息。

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

    当重置集群后,需同步删除 $HOME/.kube 目录

rm -rf $HOME/.kube

     10. 当需要在 master 节点上布署服务时(启动pod),则需要修改master 节点污点配置

     查看污点信息:

     kubectl describe node master |grep Taints

     结果:  Taints:             node-role.kubernetes.io/control-plane:NoSchedule

      去除污点NoSchedule,最后一个"-"代表删除

       kubectl taint nodes master node-role.kubernetes.io/control-plane:NoSchedule-

      备注:

         NoSchedule : 一定不被调度 但是不会驱逐已有的 这个部署 ingress-controller 的时候 有用
         PreferNoSchedule : 尽量不被调度
         NoExecute : 不会调度,并且还会驱逐Node已有Pod 这个很坏

      11.  修改 kubernetes 布署服务时,使用的端口范围。如果不需要调整,可以不用修改。

                  k8s的node节点的端口默认被限制在30000-32767的范围

          编辑 kube-apiserver.yaml文件
           vi /etc/kubernetes/manifests/kube-apiserver.yaml
          在spec.containers.command的最后面加上
              - --service-node-port-range=1-65535       

         重启 kubelet

          systemctl daemon-reload
          systemctl restart kubelet

 

      12. 部署网络插件 kube-flannel 

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml 

  如果 wget 下载失败,则新建 kube-flannel.yml, 并复制如下内容。

---
kind: Namespace
apiVersion: v1
metadata:
  name: kube-flannel
  labels:
    pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
       #image: flannelcni/flannel-cni-plugin:v1.1.0 for ppc64le and mips64le (dockerhub limitations may apply)
        image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
       #image: flannelcni/flannel:v0.20.0 for ppc64le and mips64le (dockerhub limitations may apply)
        image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
       #image: flannelcni/flannel:v0.20.0 for ppc64le and mips64le (dockerhub limitations may apply)
        image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
View Code

三:检查 kubernetes 布署是否成功

kubectl cluster-info:查看 k8s 集群信息,包括 API Server 的地址和版本以及控制平面组件的状态。

kubectl get nodes:查看集群中的节点信息,包括节点名称、IP 地址、状态和运行时间等。

kubectl get pods:查看当前命名空间下的 Pod 信息,包括 Pod 名称、所属节点、容器状态、IP 地址等。

kubectl get pods,svc -o wide --all-namespaces : 查看 所有命名空间的 pods,svc 信息

kubectl get cs :  查看集群健康状态

kubectl describe service/kubernetes  

 四. kubernetes 常见问题

  问题一:

-- The start-up result is done.
Feb 02 20:51:43 master kubelet[14025]: E0202 20:51:43.774113   14025 run.go:74] "command failed" err="failed to load kubelet config file, path: /var/lib/kubelet/config.yaml, error: failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file \"/var/lib/kubelet/config.yaml\", error: open /var/lib/kubelet/config.yaml: no such file or directory"
Feb 02 20:51:43 master systemd[1]: kubelet.service: main process exited, code=exited, status=1/FAILURE
Feb 02 20:51:43 master systemd[1]: Unit kubelet.service entered failed state.
Feb 02 20:51:43 master systemd[1]: kubelet.service failed.

   containerd 配置没修改。修改后,重启服务即可。

sed -i -r '/cri/s/(.*)/#\1/' /etc/containerd/config.toml
systemctl restart containerd

 问题 二:

failed to pull and unpack image \\\"registry.k8s.io/pause:3.6\\\": failed to resolve reference

# 生成 containerd 的默认配置文件
containerd config default > /etc/containerd/config.toml

# 查看 sandbox 的默认镜像仓库在文件中的第几行
cat /etc/containerd/config.toml | grep -n "sandbox_image"

# 使用 vim 编辑器 定位到 sandbox_image,将 仓库地址修改成 阿里镜像
vim /etc/containerd/config.toml

sandbox_image = " registry.aliyuncs.com/google_containers/pause:3.6"

# 重启 containerd 服务
systemctl daemon-reload
systemctl restart containerd.service

 问题三:

E0202 22:18:22.949900    3017 memcache.go:265] couldn't get current server API group list: Get "https://10.0.0.206:6443/api?timeout=32s": tls: failed to verify certificate: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")

 当重置集群后,需同步删除 $HOME/.kube 目录

rm -rf $HOME/.kube

 问题四:

Feb 11 12:53:30 master kubelet[24455]: E0211 12:53:30.929534 24455 pod_workers.go:1300] "Error syncing pod, skipping" err="network is not ready: container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized" pod="kube-system/coredns-66f779496c-q6gr4" podUID="98364c23-bc48-45ff-a6dd-60bafc36aa3a"

重启 containerd 服务:

systemctl restart containerd

 

五. 部署 nginx 服务,检查 kubenetes 服务运行情况

   1. 创建 nginx 布署文件。

kind: Namespace
apiVersion: v1
metadata:
  name: myserver #创建namespace

---

kind: Deployment
apiVersion: apps/v1       #可查询它的api版本 kubectl explain deployment.apiVersion
metadata:               #定义pod元数据信息,可查询它的下级子字段kubectl explain deployment.metadata
  labels:               #定义deployment控制器标签
    app: nginx-deployment-label  #标签名称以键值形式定义,可以定义多个,这里标签是app值为nginx-deployment-label
  name: nginx-deployment   #deployment资源的名字
  namespace: myserver          #deployment所属的namespace,默认是defaule
spec:                   #定义Deployment中容器的详细信息,可通过kubectl explain deployment.spec查询
  replicas: 1           #定义创建出pod的副本数,默认值是1个pod
  selector:             #定义标签选择器,它跟上面的Deployment标签不是一回事,它是找下面template中定义的labels标签
    matchLabels:        #定义匹配的标签,必须要设置
      app: nginx-selector       #匹配的目标标签,控制器会拿这个标签匹配下面的pod
  template:             #定义模板,用来描述需要创建的pod作用
    metadata:           #定义模板元数据
      labels:             #这个labels会继承给这个yaml文件Deployment控制器创建的所有pod
        app: nginx-selector   #这个labels的key是app,值是nginx-selector,它会继承给下面的pod,和上面matchLabels.app: nginx-selector一样
    spec:                  #定义pod的详细信息
      containers:          #定义pod中容器列表,可以定义多个pod
      - name: nginx-container     #容器名称
        image: nginx:1.20       #容器镜像
        imagePullPolicy: Always                       #镜像拉取策略
        ports:                    #定义容器端口列表
        - containerPort: 80     #定义一个端口
          protocol: TCP           #定义协议
          name: http              #端口名称
        - containerPort: 443
          protocol: TCP
          name: https
        env:                      #给容器传递环境变量
        - name: "password"        #变量名称,必须引号引起来
          value: "123"            #上面变量的值
        - name: "age"
          value: "18"
---
 
kind: Service
apiVersion: v1
metadata:
  name: nginx-service
  labels:
    app: nginx-service-label   #service资源的标签
  namespace: myserver          #所在的命名空间,与上面控制器必须在同一个命名空间
spec:
  type: NodePort          #service类型是NodePort  
  ports:                  #定义访问端口,一个service可以定义多个端口的映射关系
  - name: http            #定义协议名称
    port: 80              #定义service端口,它可以和pod,node端口都不同,它是K8S中一个独立子网
    protocol: TCP         #定义类型
    targetPort: 80        #目标pod端口,当访问宿主机30003端口时就会转达到pod的80端口
    nodePort: 30003       #手动指定node节点暴露的端口,如果没有指定端口,那service会随机分配一个端口
  - name: https
    port: 443
    protocol: TCP
    targetPort: 443
    nodePort: 30443
  selector:
    app: nginx-selector   #这个标签就是上面pod的标签,service通过这个标签来匹配对应的pod

 

2. 布署 nginx 服务。

kubectl apply -f nginx.yaml

 

3. 验证 nginx 服务启动成功。

curl http://127.0.0.1:30003
curl http://10.0.0.206:30003

 

4. 验证成功后,根据需要可以删除 nginx 布署信息。

  查看deployment信息
       kubectl get deployment -n <namespace>
  删除deployment配置
      kubectl delete deployment <deployment名> -n <namespace>

  删除 svc  配置

      kubectl delete svc  svc名

kubectl delete deployment nginx-deployment  -n myserver

kubectl delete svc  nginx-service -n myserver

 

六. 布署 kubernetes-dashboard 服务,进行 kubernetes 集群管理

      1. 下载 布署文件

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

 

      2. 修改 布署文件,使本机可以访问

         新增type: NodePort 和 nodePort:31443,以便能实现非本机访问

   kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 31443
  selector:
    k8s-app: kubernetes-dashboard

      3. 布署服务

kubectl apply -f  recommended.yaml

       4. 创建登录用户信息

            Dashboard 支持 Kubeconfig 和 Token 两种认证方式,暂时选择Token认证方式登录。

            a. 创建dashboard-adminuser.yaml 文件

cat > dashboard-adminuser.yaml << EOF
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: admin-user
   namespace: kubernetes-dashboard
 
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: admin-user
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
   name: cluster-admin
 subjects:
 - kind: ServiceAccount
   name: admin-user
   namespace: kubernetes-dashboard
> EOF

         b. 执行命令创建用户

kubectl apply -f dashboard-adminuser.yaml

       5. 获取 token,进行 服务登录。

kubectl -n kubernetes-dashboard create token admin-user

#生成过期时间为24小时的token
kubectl -n kubernetes-dashboard create token admin-user --duration=86400s

      待定...

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年02月19日 0

暂无评论

推荐阅读
  LcEGpXyjGQ7V   26天前   20   0   0 Kubernetes