k8s实践

k8s作为分布式集群部署方案,是一个主流的部署方案。

1. 服务器配置

至少准备3台服务器,首先修改服务器名称

hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2

将集群ip与名称写入hosts文件

echo '''
10.30.239.157 k8s-master
10.30.239.158 k8s-node1
10.30.239.159 k8s-node2
''' >> /etc/hosts

然后关闭防火墙和selinux

systemctl stop firewalld
setenforce 0

禁用swap分区,swap为0即禁用成功

swapoff -a
free -mh

添加网桥过滤和地址转发功能

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

sysctl --system

配置集群节点的免密登录

ssh-keygen -t rsa
scp -p ~/.ssh/id_rsa.pub root@k8s-node1:/root/.ssh/authorized_keys
scp -p ~/.ssh/id_rsa.pub root@k8s-node2:/root/.ssh/authorized_keys

2. yum源配置

由于本次部署的服务器为中标麒麟7.6版,首先进行yum源的配置。

配置kubernetes的yum源

vi /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

配置docker-ce的yum源。

wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

下载centos7的repo文件。

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

需要注意的是将docker-ce、centos的repo文件中的所有$releasever修改为7,否则会报错。

baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/7/os/$basearch/

yum源配置完成后,重新生成缓存

yum clean all
yum makecache

3. 安装kubernetes集群

3.1 安装kubeadm

执行如下命令,进行kubeadm等环境的安装。

yum install -y kubelet kubeadm kubectl

若报错:“Couldn’t open file /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7”
处理方法:

cd /etc/pki/rpm-gpg
wget https://www.centos.org/keys/RPM-GPG-KEY-CentOS-7 --no-check-certificate

安装完毕后,启动kubelet,此时会显示启动失败,不用处理。

systemctl start kubelet
systemctl enable kubelet
systemctl status kubelet

3.2 安装docker-ce

容器运行时环境通常是Docker,k8s版本 ≥ v1.24需要额外安装cri-dockerd。

yum install docker-ce docker-ce-cli containerd.io -y

配置镜像加速

cat<< EOF > /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://gpkhi0nk.mirror.aliyuncs.com"],
  "data-root": "/data/docker",
  "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
  "log-opts": {
   "max-size": "100m",
   "max-file": "4"
    }
}
EOF

启动docker

systemctl daemon-reload
systemctl start docker
systemctl enable docker

3.3. cri-dockerd安装

下载cri-dockerd安装包,并设置自启动。

wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.4/cri-dockerd-0.3.4-3.el7.x86_64.rpm
rpm -ivh cri-dockerd-0.3.4-3.el7.x86_64.rpm

注意k8s的1.28版本拉取镜像时会报错:detected that the sandbox image “registry.k8s.io/pause:3.6” of the container runtime is inconsistent with that used by kubeadm
在所有节点上进行处理:

systemctl stop cri-docker
vi /usr/lib/systemd/system/cri-docker.service

修改ExecStart配置,重启 cri-dockerd

ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9
systemctl daemon-reload
systemctl enable cri-docker.socket cri-docker
systemctl start cri-docker.socket cri-docker
systemctl status cri-docker.socket

3.4 kubeadm master节点初始化

–cri-socket:处理docker和cri的兼容问题
–image-repository:添加k8s镜像国内仓库地址

kubeadm init --cri-socket unix:///var/run/cri-dockerd.sock --image-repository=registry.aliyuncs.com/google_containers

重启之后reset,在执行init

kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock

日志内容如下表明初始化成功。
在这里插入图片描述
执行如下命令,将刚刚部署生成的 Kubernetes 集群的安全配置文件,保存到当前用户的.kube 目录。

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

查看k8s集群状态,此时集群处于NotReady的状态,需要通过calico进行网络支撑

kubectl get nodes

3.5 calico安装

wget https://docs.projectcalico.org/manifests/calico.yaml --no-check-certificate
kubectl apply -f  calico.yaml
# kube-system 是 Kubernetes 项目预留的系统 Pod 的工作空间,Namepsace
kubectl get pod -n kube-system

确认所有pod都处于runing状态

3.6 加入worker节点

在worker节点服务器上,将worker节点加进master节点

kubeadm join 10.30.239.157:6443 --token l4qooc.gcxyc46dkpo8ehqk --discovery-token-ca-cert-hash sha256:f359197c8932beb29f85b04f26e4bfe7ed3e1f1cbe94c4afddb855c619325844 --cri-socket unix:///var/run/cri-dockerd.sock

node节点打标签,显示为work

kubectl label nodes k8s-node1 node-role.kubernetes.io/work=work
kubectl label nodes k8s-node2 node-role.kubernetes.io/work=work

查看集群状态,所有节点都处于ready状态
在这里插入图片描述

3.7 部署 Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc6/aio/deploy/recommended.yaml
# 查看是否创建成功
kubectl get pods --all-namespaces

配置浏览器访问

kubectl get svc --all-namespaces
kubectl delete service kubernetes-dashboard --namespace=kubernetes-dashboard
vi dashboard-svc.yaml
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

创建Pod

kubectl apply -f dashboard-svc.yaml

创建kubernetes-dashboard管理员

vi dashboard-svc-account.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dashboard-admin
subjects:
  - kind: ServiceAccount
    name: dashboard-admin
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f dashboard-svc-account.yaml

查看浏览器访问端口,https://master_ip:port/#/login,采用token访问

kubectl get svc --all-namespaces
# 获取token
kubectl -n kubernetes-dashboard create token kubernetes-dashboard

浏览器页面报错:secrets is forbidden: User “system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard” cannot list resource “secrets” in API group “” in the namespace “default”。
在这里插入图片描述
安装yaml时,已创建了一个用户kubernetes-dashboard,可通过如下命令查看其详情

kubectl describe serviceaccount/kubernetes-dashboard -n kubernetes-dashboard

kubernetes 集群安装好后,会自动生成一些 clusterroles 集群权限对象,可以用下面的命令查看。

kubectl get clusterroles

查看集群管理员详情,*号表示对所有资源有所有权限

kubectl describe clusterroles cluster-admin

将服务账户 kubernetes-dashboard 跟 cluster-admin 集群管理员权限对象绑定

vi kubernetes-dashboard-ClusterRoleBinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
kubectl apply -f kubernetes-dashboard-ClusterRoleBinding.yaml

若报错:cannot change roleRef,则执行如下命令,删除后再重新创建

kubectl delete -f kubernetes-dashboard-ClusterRoleBinding.yaml

查看是否创建成功

kubectl get clusterrolebindings kubernetes-dashboard

重新登录后,dashbord页面即可正常显示
在这里插入图片描述

3.8 搭建docker 私有仓库

由于经常需要再离线环境中使用预先准备的image,因此学习下如何搭建私有仓库

docker pull docker.io/registry

启动registry容器

docker run -d -p 5000:5000 --restart always --name registry -v /home/images:/var/lib/registry -e REGISTRY_STORAGE_DELETE_ENABLED="true"  registry:latest

在浏览器上访问:http://ip:5000/v2/_catalog,此时提示仓库为空。
配置信任源,让docker使用http协议,重启docker

vi /etc/docker/daemon.json
{ 
    "insecure-registries" : [ "ip:5000" ] 
}
systemctl restart docker

将预先准备的镜像加载至docker

docker load --input /opt/web.tar

打tag,并推送至仓库

docker tag web:20231130 <ip>:5000/web:20231130
docker push <ip>:5000/web:20231130

出现该提示即推送成功

curl -XGET -s  http://ip:5000/v2/_catalog | python -m json.tool

在这里插入图片描述

3.9 nfs挂载

k8s通过pv与pvc进行持久化存储,创建pv.yaml, pvc.yaml,需要注意的是pvc中storageClassName参数需要与绑定的pv值一致,且storage不得超过pv的storage值

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.30.239.159
    path: "/opt/data"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: manual
  resources:
    requests:
      storage: 1Gi

在所有需要挂载nfs服务的集群节点上执行如下命令:

yum install nfs-utils -y
systemctl start nfs

在远程共享存储服务器上安装nfs,并将挂载目录授权给集群节点使用

vim /etc/exports
/opt/data 10.30.239.159(rw,sync,no_subtree_check,no_root_squash,insecure)

创建pv与pvc的pod

kubectl apply -f k8s/pv.yaml
kubectl apply -f k8s/pvc.yaml

4. 测试部署nginx

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get service

通过浏览器访问,http://<集群任一ip>:/

5. 常用命令与处理

#查看pod状态
# -owide:查看更多信息,如ip等
# -n:指定命名空间
kubectl get pod -n kube-system 

删除pod

kubectl delete pod <pod_name>

删除pod时,由于replicas机制,可能导致pod会被自动重新创建,此时,必须删除Pod控制器

# 查看Pod控制器
kubectl get deploy
# 删除控制器
# pod会被自动删除
kubectl delete deploy <deploy_name>

非master节点执行上述命令时报错:The connection to the server localhost:8080 was refused
处理方法:

# 将master上的admin.conf复制到worker节点
scp /etc/kubernetes/admin.conf root@k8s-node2:/etc/kubernetes/admin.conf
# 在非master节点上执行
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile

6. sealos部署k8s

安装sealos

wget https://github.com/labring/sealos/releases/download/v4.1.3/sealos_4.1.3_linux_amd64.tar.gz
tar zxvf sealos_4.1.3_linux_amd64.tar.gz sealos
chmod +x sealos
cp sealos /usr/bin
sealos version

部署命令:

sealos init \
    --master 192.168.0.2 \
    --master 192.168.0.3 \
    --master 192.168.0.4 \          # master地址列表
    --node 192.168.0.5 \            # node地址列表
    --user root \                   # 服务用户名
    --passwd your-server-password \ # 服务器密码,用于远程执行命令
    --pkg kube1.14.1.tar.gz  \      # 离线安装包名称
    --version v1.14.1               # kubernetes 离线安装包版本,这渲染kubeadm配置时需要使用

7. 使用k8s启动django服务

编写yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: django-example
  labels:
    app: django-example
spec:
  replicas: 1
  selector:
    matchLabels:
      app: django-example
  template:
    metadata:
      labels:
        app: django-example
    spec:
      containers:
      - name: web-app
        image: django-example:v1.0
        ports:
        - containerPort: 80

创建pod

kubectl apply -f django.yaml

查看pod

kubectl get pod

若pod创建失败,采用如下命令查看失败详情

kubectl describe po <pod_name>

进入pod

kubectl exec -it <pod_name> -- /bin/sh

空命令,避免报错:Back-off restarting failed container web-app in pod

command: [ "/bin/bash", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]

8. 定时任务调度

编写job.yaml

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

查看与删除cronjob

kubectl get cronjob
kubectl delete cronjob hello

查看cronjob的执行记录

kubectl get jobs --watch

查看某次执行的日志

pods=$(kubectl get pods --selector=job-name=hello-28394362 --output=jsonpath={.items..metadata.name})
kubectl logs $pods

附录

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
          path: string
        items:     
        - key: string
          path: string
      configMap:             #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
        name: string
        items:
        - key: string
          path: string
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值