阿里云服务器centos_7_9_x64位,3台,搭建k8s集群

目录

1.环境信息

2.搭建过程

2.1 安装Docker源

2.2  安装Docker

2.3 安装kubeadm,kubelet和kubectl

2.4 部署Kubernetes Master(node1)

2.5 安装Pod网络插件(CNI)

2.6 加入Kubernetes Node

2.7 测试kubernetes集群

3.部署 Dashboard

 3.1 在node1上新建文件:kubernetes-dashboard.yaml

3.2 Docker拉去镜像


1.环境信息

阿里云服务器每台服务器可有两个IP,一个是供外网直接访问,另一个内网,我的服务器配置是:

172.16.247.250  node1
172.16.247.248  node2
172.16.247.249  node3

通xshell连接,我配置node1就是master

关闭防火墙(所有服务器上执行)

systemctl stop firewalld
systemctl disable firewalld

关闭selinux

 sed -i 's/enforcing/disabled/' /etc/selinux/config 
 setenforce 0

关闭swap

swapoff -a # 临时关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab  #永久关闭

将桥接的IPv4流量传递到iptables的链

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

2.搭建过程

所有节点安装Docker/kubeadm/kubelet

2.1 安装Docker源

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

2.2  安装Docker

yum -y install docker-ce-18.06.1.ce-3.el7

开启自启和启动

systemctl enable docker && systemctl start docker

查看版本

docker --version

2.3 安装kubeadm,kubelet和kubectl

添加阿里云YUM的软件源

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
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装kubeadm,kubelet和kubectl  ,由于版本更新频繁,这里指定版本号部署:

yum install -y kubelet-1.15.0 kubeadm-1.15.0 kubectl-1.15.0

设置开机自启

systemctl enable kubelet

2.4 部署Kubernetes Master(node1)

kubeadm init \
--apiserver-advertise-address=172.16.247.250 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.15.0 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16

在node1上执行

使用kubectl工具

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

2.5 安装Pod网络插件(CNI)

在node1服务器上新建文件:kube-flannel.yml

---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp.flannel.unprivileged
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
  privileged: false
  volumes:
  - configMap
  - secret
  - emptyDir
  - hostPath
  allowedHostPaths:
  - pathPrefix: "/etc/cni/net.d"
  - pathPrefix: "/etc/kube-flannel"
  - pathPrefix: "/run/flannel"
  readOnlyRootFilesystem: false
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
rules:
- apiGroups: ['extensions']
  resources: ['podsecuritypolicies']
  verbs: ['use']
  resourceNames: ['psp.flannel.unprivileged']
- 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-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  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-system
  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: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.0.0
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: quay.io/coreos/flannel:v0.15.1
        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: quay.io/coreos/flannel:v0.15.1
        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
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      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

然后在node1上执行:

kubectl apply -f kube-flannel.yml

2.6 加入Kubernetes Node

剩下的node2 node3分别执行:

docker pull lizhenliang/flannel:v0.11.0-amd64

向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

kubeadm join 172.16.247.250:6443 --token y7z5d4.3q8basg1rhwfqeo2 \
    --discovery-token-ca-cert-hash sha256:775f6b8fe3c32065d76cc670e48757135e2d1be30b4362e0c80f9f190f2356c2 

查看Node

 kubectl get node

 node1 服务器上执行

2.7 测试kubernetes集群

在Kubernetes集群中创建一个pod,验证是否正常运行:
创建nginx容器

 kubectl create deployment nginx --image=nginx

暴露对外端口

 kubectl expose deployment nginx --port=80 --type=NodePort

查看nginx是否运行成功

 kubectl get pod,svc

这个时候,在阿云安全组,打开这个端口可访问,否则是无法访问的确

浏览器分别执行:

http://47.100.41.232:30415/
http://101.132.190.9:30415/
http://101.132.190.9:30415/

三个结点都可访问,说明集群已经搭建完成

扩容nginx副本wei3个,成功

kubectl scale deployment nginx --replicas=3
kubectl get pods

3.部署 Dashboard

 3.1 在node1上新建文件:kubernetes-dashboard.yaml

# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ------------------- Dashboard Secret ------------------- #

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kube-system
type: Opaque

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
rules:
  # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create"]
  # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
  verbs: ["get", "update", "delete"]
  # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["kubernetes-dashboard-settings"]
  verbs: ["get", "update"]
  # Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
  resources: ["services"]
  resourceNames: ["heapster"]
  verbs: ["proxy"]
- apiGroups: [""]
  resources: ["services/proxy"]
  resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
  verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: kubernetes-dashboard-minimal
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
  name: kubernetes-dashboard
  namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kube-system
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
      - name: kubernetes-dashboard
        image: lizhenliang/kubernetes-dashboard-amd64:v1.10.1
        ports:
        - containerPort: 8443
          protocol: TCP
        args:
          - --auto-generate-certificates
          # Uncomment the following line to manually specify Kubernetes API server Host
          # If not specified, Dashboard will attempt to auto discover the API server and connect
          # to it. Uncomment only if the default does not work.
          # - --apiserver-host=http://my-address:port
        volumeMounts:
        - name: kubernetes-dashboard-certs
          mountPath: /certs
          # Create on-disk volume to store exec logs
        - mountPath: /tmp
          name: tmp-volume
        livenessProbe:
          httpGet:
            scheme: HTTPS
            path: /
            port: 8443
          initialDelaySeconds: 30
          timeoutSeconds: 30
      volumes:
      - name: kubernetes-dashboard-certs
        secret:
          secretName: kubernetes-dashboard-certs
      - name: tmp-volume
        emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

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

3.2 Docker拉去镜像

docker pull  lizhenliang/kubernetes-dashboard-amd64:v1.10.1

执行kubernetes-dashboard.yaml 文件

 kubectl apply -f kubernetes-dashboard.yaml 

查看暴露的端口

kubectl get pods,svc -n kube-system

访问 Dashboard的web界面注意,http,是无法访问的

阿里云服务器还得开通端口访问才可以:

https://47.100.41.232:30001/#!/login

创建service account并绑定默认cluster-admin管理员集群角色

kubectl create serviceaccount dashboard-admin -n kube-system
 kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
 kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

三台服务器都可以访问到

https://47.100.41.232:30001/#!/storageclass?namespace=default
https://101.132.190.9:30001/#!/overview?namespace=default
https://101.132.186.133:30001/#!/overview?namespace=default

 k8s集群搭建完成

参考文献:

kubeadm部署Kubernetes(k8s)完整版详细教程_kubadm 安装k8s-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/375984.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

webrtc native api的几个要点

文章目录 基本流程状态回调类sdp的中媒体行pc对象 基本流程 webrtc native的接口&#xff0c;主要就是围绕着PeerConnection对象&#xff0c;一个PeerConnection对象它代表了一次音视频会话。 那么通过PeerConnection对象建立音视频通话&#xff0c;包括如下步骤&#xff1a; …

回归预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现POA-BP鹈鹕算法优化BP神经网络多变量回归预测&#xff08;完整源码…

光伏板安装角度有什么讲究?

随着太阳能技术的日益普及&#xff0c;光伏板&#xff08;也称为太阳能电池板&#xff09;已成为我们日常生活中不可或缺的一部分。在安装光伏板时&#xff0c;选择合适的安装角度是一个至关重要的环节&#xff0c;它直接影响到光伏系统的效率和发电量。本文将探讨光伏板安装角…

RabiitMQ延迟队列(死信交换机)

Dead Letter Exchange&#xff08;死信交换机&#xff09; 在MQ中&#xff0c;当消息成为死信&#xff08;Dead message 死掉的信息&#xff09;后&#xff0c;消息中间件可以将其从当前队列发送到另一个队列中&#xff0c;这个队列就是死信队列。而 在RabbitMQ中&#xff0c;由…

Android14音频进阶:MediaPlayerService如何启动AudioTrack 上篇(五十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

正确入市时机3秒抓住,WeTrade众汇无偿实例分享

在上篇文章中&#xff0c;WeTrade众汇无偿分享如何3秒抓住正确入市的时机&#xff0c;今天让我们通过一个例子来验证这个策略的正确性。 对于突破策略&#xff0c;WeTrade众汇用了同样的图表来演示挤压交易。蓝色箭头表示变窄的区域&#xff0c;红色箭头表示烛台穿过下层。当它…

成功解决RuntimeError: batch2 must be a 3D tensor

成功解决RuntimeError: batch2 must be a 3D tensor。 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;问题初探&#xff1a;为什么会出现这个错误&#xff1f;&#x1f333;&#x1f333;解决方案&#xff1a;如何避免和修复这个错误&#x…

啤酒:探索精酿啤酒与川菜的麻辣味觉之旅

在中国的饮食文化中&#xff0c;川菜以其麻辣味道而闻名于世。当Fendi Club啤酒遇上川菜&#xff0c;会碰撞出怎样的味觉火花&#xff1f;今天&#xff0c;让我们一起踏上这场探索Fendi Club啤酒与川菜麻辣味觉之旅。 首先&#xff0c;让我们来了解一下Fendi Club啤酒。这款啤酒…

mfc110.dll是什么?解决mfc110.dll丢失windows系统常见问题

今天我在打开电脑软件时候&#xff0c;突然报错出现找不到mfc110.dll丢失&#xff0c;无法打开软件&#xff0c;我不知道是什么原因&#xff0c;后面找了很久才找到解决方法&#xff0c;那么mfc110.dll是什么&#xff1f;为什么会丢失和mfc110.dll解决方法是什么&#xff0c;今…

年货大数据(年货节数据/电商行业数据):龙年再添两个黑马食品饮料品类,增长11倍!

年货零食三大件&#xff1a;牛奶、糖果和炒货。今年再多两大件&#xff0c;礼品卡券和腊味。 根据鲸参谋数据显示&#xff0c;今年坚果炒货、糖果、牛奶乳品、饮料等品类依然是长期的年货热门品类。1月前三周&#xff0c;牛奶乳品销量环比增长68%&#xff0c;销售额环比增长55…

ThreadLocal及阿里(TransmittableThreadLocal,TTL)分析

TTL类关系图 ThreadLocal <- InheritableThreadLocal <- TransmittableThreadLocal 1. ThreadLocal ThreadLocal 类提供线程本地&#xff08;局部&#xff09;变量。每个线程都有自己独立初始化的变量副本。 TheadLocal 允许我们存储仅由特定线程访问的数据&#xff0c;…

C#在既有数组中插入另一个数组:Array.Copy方法 vs 自定义插入方法

目录 一、使用的方法 1.使用Array.Copy方法 2.Copy(Array, Int32, Array, Int32, Int32) 3. 使用自定义的方法 二、实例 1.示例1&#xff1a;使用Array.Copy方法 2.示例2&#xff1a;使用自定义的方法 一、使用的方法 1.使用Array.Copy方法 首先定义了一个名为InsertAr…

可解释性AI(XAI):开启AI决策过程透明化,重塑信任与解决伦理偏见

文章目录 每日一句正能量前言可解释性AI的定义与重要性什么是可解释性&#xff1f;促进技术应用的可信度提高技术的透明度保护隐私和数据权益促进AI的社会接受度 可解释性AI的挑战与难点可解释性AI的应用场景后记 每日一句正能量 宁可因高目标而脖子硬&#xff0c;也不要为低目…

Java+SpringBoot:构建稳定高效的计算机基础教学平台

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

《Java程序设计》实验报告(四)之数据库操作

实验内容及步骤&#xff1a; 数据库的建立、删除等。&#xff08;1&#xff09;代码&#xff1a; package liyuxuan.study.java; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class CreateD…

npm 上传一个自己的应用(5) 删除自己发送到NPM官网的指定工具版本

上文 npm 上传一个自己的应用(4) 更新自己上传到NPM中的工具版本 并就行内容修改 我们更新了项目内容 然后更新了项目版本 那么 一些已经过时 甚至 当时上传的东西就有问题 我们又该怎么删除版本呢&#xff1f; 首先 我们还是要先登录 npm npm login然后 根据要求填写 Userna…

迅为RK3588开发板windows与开发板互传使用U盘进行拷贝

1 将 U 盘(U 盘的格式必须为 FAT32 格式&#xff0c;大小在 32G 以下)插到开发板的 usb 接口&#xff0c;串口打印信息如下所示&#xff0c;U 盘的设备节点是/dev/sdb4。U 盘的设备节点不是固定的&#xff0c;根据实际情况来查看设备节点。 2 输入以下命令挂载 U 盘&#xff0c…

新版本nginx安装提示需要openssl的问题

新版本的nginx安装的时候未发现openssl的路径&#xff0c;有两种方式解决 方式一&#xff1a; 找到本地nginx的解压目录中 &#xff0c;例如我的放到root下面了。 进入 /root/nginx1.24.0/auto/lib/openssl/conf 目录下修改内容 &#xff0c;这两行都需要修改&#xff0c;…

华为配置访客接入WLAN网络示例(MAC优先的Portal认证)

配置访客接入WLAN网络示例&#xff08;MAC优先的Portal认证&#xff09; 组网图形 图1 配置WLAN MAC优先的Portal认证示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 某企业为了提高WLAN网络的安全性&#xff0c;采用MAC优先的外置Portal认…

【51单片机】外部中断和定时器中断

目录 中断系统中断介绍中断概念 中断结构及相关寄存器中断结构中断相关寄存器 外部中断实验外部中断配置软件设计实验现象 定时器中断定时器介绍51 单片机定时器原理51 单片机定时/计数器结构51 单片机定时/计数器的工作方式 定时器配置硬件设计软件设计实验现象 中断系统 本章…