当前位置: 首页 > news >正文

建设网站答辩情况个人电脑做网站主机

建设网站答辩情况,个人电脑做网站主机,后盾网原创实战网站建设教程,长沙网站制作哪家强文章目录 一、helm二、K8S/K3S1.K8S基本组件1.1 资源对象1.2 核心组件1.3典型的创建 Pod 的流程1.4 Kubernetes 多组件之间的通信原理 2. YAML 文件2.1 Maps2.2 Lists2.3 使用 YAML 创建 Pod2.4 创建 Deployment 3.用 kubeadm 搭建集群环境3.1 环境3.2 镜像#xff08;如果你的… 文章目录 一、helm二、K8S/K3S1.K8S基本组件1.1 资源对象1.2 核心组件1.3典型的创建 Pod 的流程1.4 Kubernetes 多组件之间的通信原理 2. YAML 文件2.1 Maps2.2 Lists2.3 使用 YAML 创建 Pod2.4 创建 Deployment 3.用 kubeadm 搭建集群环境3.1 环境3.2 镜像如果你的节点上面有科学上网的工具可以忽略这一步3.3安装 kubeadm、kubelet、kubectl3.4配置 kubelet3.5集群安装初始化3.6安装 Pod Network3.7添加节点 4.静态pod4.1 配置文件4.2 通过 HTTP 创建静态 Pods4.3 静态pods的动作行为4.4 静态pods的动态增加和删除 5Pod Hook5.1环境准备5.2优雅删除资源对象 6 Pod健康检查6.1 livenessProbe:exec6.2 livenessProbe:httpGet6.3 livenessProbe/readinessProbe:tcpSocket 7 初始化容器initContainers 三、容器运行时 Containerd1.查看当前k3s使用的容器运行时CRI2.K3S修改docker为运行环境 参考 一、helm Helm是Kubernetes的包管理器 chart代表helm包包含在Kubernetes集群内允许额应用程序工具或者服务所需的所有资源定义Repository用来存放和共享charts的地方Releasechart名字允许在Kubernetes集群中的chart的实例一个chart通过可以在同一个集群中安装多次每一次安装都会创建一个新的release 部署一个简单的helm chart 环境ubuntu20.04 helm版本 ➜ ~ helm version version.BuildInfo{Version:v3.14.3, GitCommit:f03cc04caaa8f6d7c3e67cf918929150cf6f3f12, GitTreeState:clean, GoVersion:go1.21.7}1创建nginx-chart ➜ mender helm create nginx-chart2开始部署 简单起见删除templates下的所有文件并创建新的yaml文件。 ➜ mender tree nginx-chart nginx-chart ├── Chart.yaml ├── charts ├── templates │ ├── deployment.yaml │ ├── namespace.yaml │ └── service.yaml └── values.yaml2 directories, 5 filesservice.yaml apiVersion: v1 kind: Service metadata:name: nginx-server-svcnamespace: nginx-ns spec:ports:- port: 80targetPorts: 80nodePort: 30119selector:app: nginx-servertype: NodePort deployment.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-deploymentnamespace: nginx-nslabels:app: nginx-server spec:replicas: 3selector:matchLabels:app: nginx-servertemplate:metadata:labels:app: nginx-serverspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80 namespace.yaml apiVersion: v1 kind: Namespace metadata:name: nginx-ns ➜ mender helm install nginx ./nginx-chart W0407 12:27:42.406153 345264 warnings.go:70] unknown field spec.ports[0].targetPorts NAME: nginx LAST DEPLOYED: Sun Apr 7 12:27:42 2024 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None3查询 ➜ mender helm list 使用kubectl查询pod状态 ➜ ~ kubectl get pods -A使用kubectl查询service状态 ➜ ~ kubectl get svc -n ningxin-ns4其他命令 删除 ➜ ~ helm uninstall nginx release nginx uninstalled仓库相关 列表 ➜ ~ helm repo list增加仓库 helm repo add stable http://a/b/c/charts stable为仓库名help repo remove 仓库名 helm search repo tomcat helm pull stable/tomcat --untar 拉取chart包stable为名字查看详细信息 helm get manifest ${release_name}安装 helm install name chart目录 helm install myconfigmap3 ./mychart/ --debug --dry-runhelm shou chart stable/tomcat 升级 修改values.yaml内容如下 nginx:replicas: 1修改deployment.yaml内容如下 yamlreplicas: {{ .Values.nginx.replica }}启动 powershell ➜ mender helm install nginx ./nginx-chart修改values.yaml中的内容 nginx:replica: 5升级values ➜ mender helm upgrade nginx ./nginx-chart -f ./nginx-chart/values.yaml W0407 14:05:07.113651 703702 warnings.go:70] unknown field spec.ports[0].targetPorts Release nginx has been upgraded. Happy Helming! NAME: nginx LAST DEPLOYED: Sun Apr 7 14:05:06 2024 NAMESPACE: default STATUS: deployed REVISION: 2 TEST SUITE: None升级结果 ➜ mender kubectl get pod -n nginx-ns NAME READY STATUS RESTARTS AGE nginx-deployment-6f5d4c59d9-krwwr 1/1 Running 0 77m nginx-deployment-6f5d4c59d9-vrvft 1/1 Running 0 68m nginx-deployment-6f5d4c59d9-4lmsb 1/1 Running 0 68m nginx-deployment-6f5d4c59d9-mbntc 1/1 Running 0 68m nginx-deployment-6f5d4c59d9-4v9j2 1/1 Running 0 68m回滚 ➜ mender kubectl get pod -n nginx-ns NAME READY STATUS RESTARTS AGE nginx-deployment-6f5d4c59d9-krwwr 1/1 Running 0 77m nginx-deployment-6f5d4c59d9-vrvft 1/1 Running 0 68m nginx-deployment-6f5d4c59d9-4lmsb 1/1 Running 0 68m nginx-deployment-6f5d4c59d9-mbntc 1/1 Running 0 68m nginx-deployment-6f5d4c59d9-4v9j2 1/1 Running 0 68m ➜ mender helm ls NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager default 1 2024-04-03 15:25:17.13140855 0800 CST deployed cert-manager-v1.4.0 v1.4.0 mender default 8 2024-04-03 17:44:33.157426499 0800 CST failed mender-5.6.0 3.7.3 minio-operator default 1 2024-04-03 15:27:49.145957089 0800 CST deployed minio-operator-4.1.7 v4.1.3 my-release default 1 2024-04-03 15:36:50.207554144 0800 CST deployed mongodb-15.1.1 7.0.7 nginx default 2 2024-04-07 14:05:06.944673306 0800 CST deployed nginx-chart-0.1.0 1.16.0 ➜ mender helm rollback nginx 1 W0407 15:15:05.193720 959270 warnings.go:70] unknown field spec.ports[0].targetPorts Rollback was a success! Happy Helming! ➜ mender helm ls NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager default 1 2024-04-03 15:25:17.13140855 0800 CST deployed cert-manager-v1.4.0 v1.4.0 mender default 8 2024-04-03 17:44:33.157426499 0800 CST failed mender-5.6.0 3.7.3 minio-operator default 1 2024-04-03 15:27:49.145957089 0800 CST deployed minio-operator-4.1.7 v4.1.3 my-release default 1 2024-04-03 15:36:50.207554144 0800 CST deployed mongodb-15.1.1 7.0.7 nginx default 3 2024-04-07 15:15:05.132864163 0800 CST deployed nginx-chart-0.1.0 1.16.0 可以看到只有一个nginx了删除了其他3个镜像 ➜ mender kubectl get pod -n nginx-ns NAME READY STATUS RESTARTS AGE nginx-deployment-6f5d4c59d9-krwwr 1/1 Running 0 79m二、K8S/K3S 1.K8S基本组件 1.1 资源对象 MasterMaster节点是K8S集群的控制节点负责整个集群的管理和控制。Master节点上包含以下组件 kube-apiserver集群控制的入口提供HTTP REST服务。包含8080的非安全服务、6443安全服务kube-controller-managerK8S集群中所有资源对象的自动化控制中心kube-scheduler负责Pod的调用 NodeNode节点是K8S集群中的工作节点Node上的工作负载由Master节点分配工作负载主要是运行容器应用。 Node节点包含以下组件 kubelet负责Pod的创建、启动、监控、重启、销毁灯工作同时与Master节点协作实现集群管理的基本功能。kube-proxy实现K8S Service的通信和负载均衡运行容器化Pod应用 PodPod是K9S最基本的部署调度单元每个Pod可以由一个或者多个业务容器和一个根容器(Pause容器)组成。一个Pod表示某个应用的一个是实例。 ReplicaSet是Pod副本的抽象用于解决Pod的扩容和伸缩。 DeploymentDeployment表示部署在内部使用ReplicaSet来实现。可以通过Deployment来生成相应的ReplicaSet完成Pod副本的创建。 ServiceService是K8S最重要的资源对象K8S中的Service对象可以对应微服务架构中的微服务。Service定义了服务的访问入口服务的调用者通过这个地址访问Service后端的Pod副本实例。Service通过Label Selector同后端的Pod副本建立关系Deployment保证后端Pod副本的数量也就是保证服务的伸缩性。 1.2 核心组件 Kubernetes 主要由以下几个核心组件组成: etcd 保存了整个集群的状态就是一个数据库 apiserver 提供了资源操作的唯一入口并提供认证、授权、访问控制、API 注册和发现等机制 controller manager 负责维护集群的状态比如故障检测、自动扩展、滚动更新等 scheduler 负责资源的调度按照预定的调度策略将 Pod 调度到相应的机器上 kubelet 负责维护容器的生命周期同时也负责 VolumeCSI和网络CNI的管理 Container runtime 负责镜像管理以及 Pod 和容器的真正运行CRI kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡 当然了除了上面的这些核心组件还有一些推荐的插件 kube-dns 负责为整个集群提供 DNS 服务 Ingress Controller 为服务提供外网入口 Heapster 提供资源监控 Dashboard 提供 GUI 1.3典型的创建 Pod 的流程 用户通过 REST API 创建一个 Pod apiserver 将其写入 etcd scheduluer 检测到未绑定 Node 的 Pod开始调度并更新 Pod 的 Node 绑定 kubelet 检测到有新的 Pod 调度过来通过 container runtime 运行该 Pod kubelet 通过 container runtime 取到 Pod 状态并更新到 apiserver 中 1.4 Kubernetes 多组件之间的通信原理 apiserver 负责 etcd 存储的所有操作且只有 apiserver 才直接操作 etcd 集群 apiserver 对内集群中的其他组件和对外用户提供统一的 REST API其他组件均通过 apiserver 进行通信 controller manager、scheduler、kube-proxy 和 kubelet 等均通过 apiserver watch API 监测资源变化情况并对资源作相应的操作 所有需要更新资源状态的操作均通过 apiserver 的 REST API 进行 apiserver 也会直接调用 kubelet API如 logs, exec, attach 等默认不校验 kubelet 证书但可以通过 --kubelet-certificate-authority 开启而 GKE 通过 SSH 隧道保护它们之间的通信 2. YAML 文件 它的基本语法规则如下 大小写敏感 使用缩进表示层级关系 缩进时不允许使用Tab键只允许使用空格。 缩进的空格数目不重要只要相同层级的元素左侧对齐即可 # 表示注释从这个字符一直到行尾都会被解析器忽略。 在我们的 kubernetes 中你只需要两种结构类型就行了 Lists Maps 2.1 Maps Map 是字典就是一个key:value的键值对Maps 可以让我们更加方便的去书写配置信息例如 --- apiVersion: v1 kind: Pod第一行的—是分隔符是可选的在单一文件中可用连续三个连字号—区分多个文件。这里我们可以看到我们有两个键kind 和 apiVersion他们对应的值分别是v1 和Pod。 上面的 YAML 文件转换成 JSON 格式的话: {apiVersion: v1,kind: pod }在创建一个相对复杂一点的 YAML 文件创建一个 KEY 对应的值不是字符串而是一个 Maps --- apiVersion: v1 kind: Pod metadata:name: kube100-sitelabels:app: web上面的 YAML 文件metadata 这个 KEY 对应的值就是一个 Maps 了而且嵌套的 labels 这个 KEY 的值又是一个 Map你可以根据你自己的情况进行多层嵌套。 我们可以看到 name 和 labels 是相同级别的缩进所以 YAML 处理器就知道了他们属于同一个 MAP而 app 是 labels 的值是因为 app 的缩进更大。 可以将上面的 YAML 文件转换成 JSON 文件 {apiVersion: v1,kind: Pod,metadata: {name: kube100-site,labels: {app: web}} }2.2 Lists Lists 就是列表说白了就是数组在 YAML 文件中我们可以这样定义 args- Cat- Dog- Fish你可以有任何数量的项在列表中每个项的定义以破折号-开头的与父元素直接可以缩进一个空格。对应的 JSON 格式如下 {args: [Cat, Dog, Fish] }当然list 的子项也可以是 MapsMaps 的子项也可以是list如下所示 --- apiVersion: v1 kind: Pod metadata:name: kube100-sitelabels:app: web spec:containers:- name: front-endimage: nginxports:- containerPort: 80- name: flaskapp-demoimage: jcdemo/flaskappports:- containerPort: 5000这个 YAML 文件我们定义了一个叫 containers 的 List 对象每个子项都由 name、image、ports 组成每个 ports 都有一个 key 为 containerPort 的 Map 组成同样的我们可以转成如下 JSON 格式文件 {apiVersion: v1,kind: Pod,metadata: {name: kube100-site,labels: {app: web}},spec: {containers: [{name: front-end,image: nginx,ports: [{containerPort: 80}]}, {name: flaskapp-demo,image: jcdemo/flaskapp,ports: [{containerPort: 5000}]}]} }2.3 使用 YAML 创建 Pod 创建 Pod --- apiVersion: v1 kind: Pod metadata:name: kube100-sitelabels:app: web spec:containers:- name: front-endimage: nginxports:- containerPort: 80- name: flaskapp-demoimage: jcdemo/flaskappports:- containerPort: 5000我们先来简单分析下文件内容 apiVersion这里它的值是 v1这个版本号需要根据我们安装的 kubernetes 版本和资源类型进行变化的记住不是写死的kind这里我们创建的是一个 Pod当然根据你的实际情况这里资源类型可以是 Deployment、Job、Ingress、Service 等待。metadata包含了我们定义的 Pod 的一些 meta 信息比如名称、namespace、标签等等信息。spec包括一些 containersstoragevolumes或者其他 Kubernetes 需要知道的参数以及诸如是否在容器失败时重新启动容器的属性。你可以在特定 Kubernetes API 找到完整的 Kubernetes Pod 的属性。 典型的容器的定义 …spec:containers:- name: front-endimage: nginxports:- containerPort: 80 …在这个例子中这是一个简单的最小定义一个名字front-end基于 nginx 的镜像以及容器 将会监听的一个端口80。在这些当中只有名字是非常需要的你也可以指定一个更加复杂的属性例如在容器启动时运行的命令应使用的参数工作目录或每次实例化时是否拉取映像的新副本。 以下是一些容器可选的设置属性 name image command args workingDir ports env resources volumeMounts livenessProbe readinessProbe livecycle terminationMessagePath imagePullPolicy securityContext stdin stdinOnce tty我们将上面创建 POD 的 YAML 文件保存成 pod.yaml然后使用kubectl创建 POD $ kubectl create -f pod.yaml pod kube100-site createdkubectl 命令来查看 POD 的状态了 $ kubectl get pods NAME READY STATUS RESTARTS AGE kube100-site 2/2 Running 0 1m先删除上面创建的 POD $ kubectl delete -f pod.yaml pod kube100-site deleted2.4 创建 Deployment 在上面的例子中我们只是单纯的创建了一个 POD 实例但是如果这个 POD 出现了故障的话我们的服务也就挂掉了所以 kubernetes 提供了一个Deployment的概念可以让 kubernetes 去管理一组 POD 的副本也就是副本集这样就可以保证一定数量的副本一直可用的不会因为一个 POD 挂掉导致整个服务挂掉。我们可以这样定义一个 Deployment --- apiVersion: apps/v1 kind: Deployment metadata:name: kube100-site spec:replicas: 2注意这里的apiVersion对应的值是apps/v1当然 kind 要指定为 Deployment因为这就是我们需要的然后我们可以指定一些 meta 信息比如名字或者标签之类的。最后最重要的是spec配置选项这里我们定义需要两个副本。 当然还有很多可以设置的属性比如一个 Pod 在没有任何错误变成准备的情况下必须达到的最小秒数。 我们可以在Kubernetes v1beta1 API参考中找到一个完整的 Depolyment 可指定的参数列表。 现在我们来定义一个完整的 Deployment 的 YAML 文件 --- apiVersion: apps/v1 kind: Deployment metadata:name: kube100-site spec:replicas: 2selector:matchLabels:app: webtemplate:metadata:labels:app: webspec:containers:- name: front-endimage: nginxports:- containerPort: 80- name: flaskapp-demoimage: jcdemo/flaskappports:- containerPort: 5000看起来是不是和我们上面的 pod.yaml 很类似啊注意其中的 template其实就是对 POD 对象的定义。将上面的 YAML 文件保存为 deployment.yaml然后创建 Deployment $ kubectl create -f deployment.yaml deployment kube100-site created想要查看它的状态我们可以检查 Deployment的列表 $ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE kube100-site 2 2 2 2 2m我们可以看到所有的 Pods 都已经正常运行了。 3.用 kubeadm 搭建集群环境 官方文档Creating a cluster with kubeadm k8s的架构图 核心层Nucleus Layer Kubernetes 最核心的功能对外提供 API 构建高层的应用对内提供插件式应用执行环境 应用层Application Layer 部署无状态应用、有状态应用、批处理任务、集群应用等和路由服务发现、DNS 解析等 管理层Governance Layer 系统度量如基础设施、容器和网络的度量自动化如自动扩展、动态 Provision 等以及策略管理RBAC、Quota、PSP、NetworkPolicy 等 接口层Interface Layer kubectl 命令行工具、客户端 SDK 以及集群联邦 生态系统Ecosystem Layer 在接口层之上的庞大容器集群管理调度的生态系统可以划分为两个范畴 Kubernetes 外部日志、监控、配置管理、CI、CD、Workflow等 Kubernetes 内部CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等 这里使用的是kubeadm工具来进行集群的搭建。 kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具通过将集群的各个组件进行容器化安装管理通过kubeadm的方式安装集群比二进制的方式安装要方便不少。 3.1 环境 Master节点和Node节点都需要配置 我们这里准备两台Centos7的主机用于安装后续节点可以同样需要配置 $ cat /etc/hosts 10.151.30.57 master 10.151.30.62 node01禁用防火墙 $ systemctl stop firewalld $ systemctl disable firewalld禁用SELINUX $ setenforce 0 $ cat /etc/selinux/config SELINUXdisabled创建/etc/sysctl.d/k8s.conf文件添加如下内容 net.bridge.bridge-nf-call-ip6tables 1 net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1执行如下命令使修改生效 $ modprobe br_netfilter $ sysctl -p /etc/sysctl.d/k8s.conf3.2 镜像如果你的节点上面有科学上网的工具可以忽略这一步 将所需的gcr.io上面的镜像下载到节点上面。master节点执行下面的命令 docker pull cnych/kube-apiserver-amd64:v1.10.0 docker pull cnych/kube-scheduler-amd64:v1.10.0 docker pull cnych/kube-controller-manager-amd64:v1.10.0 docker pull cnych/kube-proxy-amd64:v1.10.0 docker pull cnych/k8s-dns-kube-dns-amd64:1.14.8 docker pull cnych/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker pull cnych/k8s-dns-sidecar-amd64:1.14.8 docker pull cnych/etcd-amd64:3.1.12 docker pull cnych/flannel:v0.10.0-amd64 docker pull cnych/pause-amd64:3.1docker tag cnych/kube-apiserver-amd64:v1.10.0 k8s.gcr.io/kube-apiserver-amd64:v1.10.0 docker tag cnych/kube-scheduler-amd64:v1.10.0 k8s.gcr.io/kube-scheduler-amd64:v1.10.0 docker tag cnych/kube-controller-manager-amd64:v1.10.0 k8s.gcr.io/kube-controller-manager-amd64:v1.10.0 docker tag cnych/kube-proxy-amd64:v1.10.0 k8s.gcr.io/kube-proxy-amd64:v1.10.0 docker tag cnych/k8s-dns-kube-dns-amd64:1.14.8 k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8 docker tag cnych/k8s-dns-dnsmasq-nanny-amd64:1.14.8 k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker tag cnych/k8s-dns-sidecar-amd64:1.14.8 k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8 docker tag cnych/etcd-amd64:3.1.12 k8s.gcr.io/etcd-amd64:3.1.12 docker tag cnych/flannel:v0.10.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64 docker tag cnych/pause-amd64:3.1 k8s.gcr.io/pause-amd64:3.1其他Node执行下面的命令 docker pull cnych/kube-proxy-amd64:v1.10.0 docker pull cnych/flannel:v0.10.0-amd64 docker pull cnych/pause-amd64:3.1 docker pull cnych/kubernetes-dashboard-amd64:v1.8.3 docker pull cnych/heapster-influxdb-amd64:v1.3.3 docker pull cnych/heapster-grafana-amd64:v4.4.3 docker pull cnych/heapster-amd64:v1.4.2 docker pull cnych/k8s-dns-kube-dns-amd64:1.14.8 docker pull cnych/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker pull cnych/k8s-dns-sidecar-amd64:1.14.8docker tag cnych/flannel:v0.10.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64 docker tag cnych/pause-amd64:3.1 k8s.gcr.io/pause-amd64:3.1 docker tag cnych/kube-proxy-amd64:v1.10.0 k8s.gcr.io/kube-proxy-amd64:v1.10.0docker tag cnych/k8s-dns-kube-dns-amd64:1.14.8 k8s.gcr.io/k8s-dns-kube-dns-amd64:1.14.8 docker tag cnych/k8s-dns-dnsmasq-nanny-amd64:1.14.8 k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64:1.14.8 docker tag cnych/k8s-dns-sidecar-amd64:1.14.8 k8s.gcr.io/k8s-dns-sidecar-amd64:1.14.8docker tag cnych/kubernetes-dashboard-amd64:v1.8.3 k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.3 docker tag cnych/heapster-influxdb-amd64:v1.3.3 k8s.gcr.io/heapster-influxdb-amd64:v1.3.3 docker tag cnych/heapster-grafana-amd64:v4.4.3 k8s.gcr.io/heapster-grafana-amd64:v4.4.3 docker tag cnych/heapster-amd64:v1.4.2 k8s.gcr.io/heapster-amd64:v1.4.23.3安装 kubeadm、kubelet、kubectl Master和Node都需要执行master节点同样需要安装kubelet因为Pod是跑在kubelet上的 我们这里是通过指定yum 源的方式来进行安装的 另外还需要注意的是当前版本的 kubeadm 支持的docker版本最大是 17.03如果需要docker版本比较高建议安装高版本的kubeadm cat EOF /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://packages.cloud.google.com/yum/doc/yum-key.gpghttps://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF如果不能科学上网的话我们可以使用阿里云的源进行安装 cat EOF /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttp://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled1 gpgcheck0 repo_gpgcheck0 gpgkeyhttp://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpghttp://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF注意由于阿里云的源将依赖进行了更改如果你需要安装 1.10.0 版本的集群的话需要使用下面的命令分别安装 $ yum makecache fast $ yum install -y kubelet-1.10.0-0 $ yum install -y kubectl-1.10.0-0 $ yum install -y kubeadm-1.10.0-03.4配置 kubelet master和slave节点都需要安装 安装完成后我们还需要对kubelet进行配置因为用yum源的方式安装的kubelet生成的配置文件将参数–cgroup-driver改成了systemd而 docker 的cgroup-driver是cgroupfs这二者必须一致才行我们可以通过docker info命令查看 $ docker info |grep Cgroup Cgroup Driver: cgroupfs修改文件 kubelet 的配置文件/etc/systemd/system/kubelet.service.d/10-kubeadm.conf将其中的KUBELET_CGROUP_ARGS参数更改成cgroupfs EnvironmentKUBELET_CGROUP_ARGS--cgroup-drivercgroupfsKubernetes 从1.8开始要求关闭系统的 Swap 如果不关闭默认配置的 kubelet 将无法启动我们可以通过 kubelet 的启动参数–fail-swap-onfalse更改这个限制所以我们需要在上面的配置文件中增加一项配置(在ExecStart之前) EnvironmentKUBELET_EXTRA_ARGS--fail-swap-onfalse当然最好的还是将 swap 给关掉这样能提高 kubelet 的性能。修改完成后重新加载我们的配置文件即可 $ systemctl daemon-reload3.5集群安装初始化 准备工作就完成了 在master节点上用kubeadm命令来初始化我们的集群了 $ kubeadm init --kubernetes-versionv1.10.0 --pod-network-cidr10.244.0.0/16 --apiserver-advertise-address10.151.30.57如果无法执行就增加sudo 命令非常简单就是kubeadm init后面的参数是需要安装的集群版本因为我们这里选择flannel作为 Pod 的网络插件所以需要指定–pod-network-cidr10.244.0.0/16然后是 apiserver 的通信地址这里就是我们 master 节点的 IP 地址。 执行上面的命令如果出现running with swap on is not supported. Please disable swap之类的错误则我们还需要增加一个参数–ignore-preflight-errorsSwap来忽略 swap 的错误提示信息。 $ kubeadm init \--kubernetes-versionv1.10.0 \--pod-network-cidr10.244.0.0/16 \--apiserver-advertise-address10.151.30.57 \--ignore-preflight-errorsSwap [init] Using Kubernetes version: v1.10.0 [init] Using Authorization modes: [Node RBAC] [preflight] Running pre-flight checks.[WARNING FileExisting-crictl]: crictl not found in system pathSuggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl [preflight] Starting the kubelet service [certificates] Generated ca certificate and key. [certificates] Generated apiserver certificate and key. [certificates] apiserver serving cert is signed for DNS names [ydzs-master1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.151.30.57] [certificates] Generated apiserver-kubelet-client certificate and key. [certificates] Generated etcd/ca certificate and key. [certificates] Generated etcd/server certificate and key. [certificates] etcd/server serving cert is signed for DNS names [localhost] and IPs [127.0.0.1] [certificates] Generated etcd/peer certificate and key. [certificates] etcd/peer serving cert is signed for DNS names [ydzs-master1] and IPs [10.151.30.57] [certificates] Generated etcd/healthcheck-client certificate and key. [certificates] Generated apiserver-etcd-client certificate and key. [certificates] Generated sa key and public key. [certificates] Generated front-proxy-ca certificate and key. [certificates] Generated front-proxy-client certificate and key. [certificates] Valid certificates and keys now exist in /etc/kubernetes/pki [kubeconfig] Wrote KubeConfig file to disk: /etc/kubernetes/admin.conf [kubeconfig] Wrote KubeConfig file to disk: /etc/kubernetes/kubelet.conf [kubeconfig] Wrote KubeConfig file to disk: /etc/kubernetes/controller-manager.conf [kubeconfig] Wrote KubeConfig file to disk: /etc/kubernetes/scheduler.conf [controlplane] Wrote Static Pod manifest for component kube-apiserver to /etc/kubernetes/manifests/kube-apiserver.yaml [controlplane] Wrote Static Pod manifest for component kube-controller-manager to /etc/kubernetes/manifests/kube-controller-manager.yaml [controlplane] Wrote Static Pod manifest for component kube-scheduler to /etc/kubernetes/manifests/kube-scheduler.yaml [etcd] Wrote Static Pod manifest for a local etcd instance to /etc/kubernetes/manifests/etcd.yaml [init] Waiting for the kubelet to boot up the control plane as Static Pods from directory /etc/kubernetes/manifests. [init] This might take a minute or longer if the control plane images have to be pulled. [apiclient] All control plane components are healthy after 22.007661 seconds [uploadconfig] Storing the configuration used in ConfigMap kubeadm-config in the kube-system Namespace [markmaster] Will mark node ydzs-master1 as master by adding a label and a taint [markmaster] Master ydzs-master1 tainted and labelled with key/value: node-role.kubernetes.io/master [bootstraptoken] Using token: 8xomlq.0cdf2pbvjs2gjho3 [bootstraptoken] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials [bootstraptoken] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token [bootstraptoken] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster [bootstraptoken] Creating the cluster-info ConfigMap in the kube-public namespace [addons] Applied essential addon: kube-dns [addons] Applied essential addon: kube-proxyYour Kubernetes master has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configYou 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/You can now join any number of machines by running the following on each node as root:kubeadm join 10.151.30.57:6443 --token 8xomlq.0cdf2pbvjs2gjho3 --discovery-token-ca-cert-hash sha256:92802317cb393682c1d1356c15e8b4ec8af2b8e5143ffd04d8be4eafb5fae368要注意将上面的加入集群的命令保存下面如果忘记保存上面的 token 和 sha256 值的话也不用担心我们可以使用下面的命令来查找 $ kubeadm token list kubeadm token list TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS i5gbaw.os1iow5tdo17rwdu 23h 2018-05-18T01:32:5508:00 authentication,signing The default bootstrap token generated by kubeadm init. system:bootstrappers:kubeadm:default-node-token要查看 CA 证书的 sha256 的值的话我们可以使用openssl来读取证书获取 sha256 的值 $ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2/dev/null | openssl dgst -sha256 -hex | sed s/^.* // e9ca4d9550e698105f1d8fae7ecfd297dd9331ca7d50b5493fa0491b2b4df40c另外还需要注意的是当前版本的 kubeadm 支持的docker版本最大是 17.03所以要注意下。 上面的信息记录了 kubeadm 初始化整个集群的过程生成相关的各种证书、kubeconfig 文件、bootstraptoken 等等后边是使用kubeadm join往集群中添加节点时用到的命令 下面的命令是配置如何使用kubectl访问集群的方式以普通用户的方式使用kubectl$HOME/.kube/config是kubectl默认使用的配置文件 mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config将节点加入集群的命令 kubeadm join 10.151.30.57:6443 --token 8xomlq.0cdf2pbvjs2gjho3 --discovery-token-ca-cert-hash sha256:92802317cb393682c1d1356c15e8b4ec8af2b8e5143ffd04d8be4eafb5fae368我们根据上面的提示配置好 kubectl 后就可以使用 kubectl 来查看集群的信息了 $ kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {health: true} $ kubectl get csr NAME AGE REQUESTOR CONDITION node-csr-8qygb8Hjxj-byhbRHawropk81LHNPqZCTePeWoZs3-g 1h system:bootstrap:8xomlq Approved,Issued $ kubectl get nodes NAME STATUS ROLES AGE VERSION ydzs-master1 Ready master 3h v1.10.0如果你的集群安装过程中遇到了其他问题我们可以使用下面的命令来进行重置 $ kubeadm reset $ ifconfig cni0 down ip link delete cni0 $ ifconfig flannel.1 down ip link delete flannel.1 $ rm -rf /var/lib/cni/ 3.6安装 Pod Network 在master节点上操作 接下来我们来安装flannel网络插件 $ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml $ kubectl apply -f kube-flannel.yml clusterrole.rbac.authorization.k8s.io flannel created clusterrolebinding.rbac.authorization.k8s.io flannel created serviceaccount flannel created configmap kube-flannel-cfg created daemonset.extensions kube-flannel-ds created另外需要注意的是如果你的节点有多个网卡的话需要在 kube-flannel.yml 中使用–iface参数指定集群主机内网网卡的名称否则可能会出现 dns 无法解析。flanneld 启动参数加上–ifaceiface-name args: - --ip-masq - --kube-subnet-mgr - --ifaceeth0安装完成后使用 kubectl get pods 命令可以查看到我们集群中的组件运行状态如果都是Running 状态的话那么恭喜你你的 master 节点安装成功了。 $ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system etcd-ydzs-master1 1/1 Running 0 10m kube-system kube-apiserver-ydzs-master1 1/1 Running 0 10m kube-system kube-controller-manager-ydzs-master1 1/1 Running 0 10m kube-system kube-dns-86f4d74b45-f5595 3/3 Running 0 10m kube-system kube-flannel-ds-qxjs2 1/1 Running 0 1m kube-system kube-proxy-vf5fg 1/1 Running 0 10m kube-system kube-scheduler-ydzs-master1 1/1 Running 0 10m查询集群中node 默认情况下普通的node不会被调度到master的node上的 ➜ Updater kubectl get nodes3.7添加节点 在node上操作 同样的上面的环境配置、docker 安装、kubeadm、kubelet、kubectl 这些都在Node(10.151.30.62)节点安装配置好过后; 我们就可以直接在 Node 节点上执行kubeadm join命令了上面初始化的时候有同样加上参数–ignore-preflight-errorsSwap: $ kubeadm join 10.151.30.57:6443 --token 8xomlq.0cdf2pbvjs2gjho3 --discovery-token-ca-cert-hash sha256:92802317cb393682c1d1356c15e8b4ec8af2b8e5143ffd04d8be4eafb5fae368 --ignore-preflight-errorsSwap [preflight] Running pre-flight checks.[WARNING Swap]: running with swap on is not supported. Please disable swap[WARNING FileExisting-crictl]: crictl not found in system path Suggestion: go get github.com/kubernetes-incubator/cri-tools/cmd/crictl [discovery] Trying to connect to API Server 10.151.30.57:6443 [discovery] Created cluster-info discovery client, requesting info from https://10.151.30.57:6443 [discovery] Requesting info from https://10.151.30.57:6443 again to validate TLS against the pinned public key [discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server 10.151.30.57:6443 [discovery] Successfully established connection with API Server 10.151.30.57:6443This node has joined the cluster: * Certificate signing request was sent to master and a responsewas received. * The Kubelet was informed of the new secure connection details.Run kubectl get nodes on the master to see this node join the cluster.如果出现下面的错误信息[discovery] Failed to request cluster info, will try again: [Get https://10.151.30.27:6443/api/v1/namespaces/kube-public/configmaps/cluster-info: x509: certificate has expired or is not yet valid]应该是 master 和 node 之间时间不同步造成的执行 ntp 时间同步后重新 init、join 即可。 如果 join 的时候出现下面的错误信息[ERROR CRI]: unable to check if the container runtime at “/var/run/dockershim.sock” is running: fork/exec /usr/bin/crictl -r /var/run/dockershim.sock info: no such file or directory这个是因为 cri-tools 版本造成的错误可以卸载掉即可yum remove cri-tools。 我们可以看到该节点已经加入到集群中去了然后我们把 master 节点的~/.kube/config文件拷贝到当前节点对应的位置即可使用 kubectl 命令行工具了。 $ kubectl get nodes NAME STATUS ROLES AGE VERSION evjfaxic Ready none 1h v1.10.0 ydzs-master1 Ready master 3h v1.10.0查看所有节点证书 ➜ Updater kubectl get csr查看在所有节点上运行的pod ➜ Updater kubectl get pods -A -o wide4.静态pod K3S不支持。 K3s 依赖的数据库能否使用static pod启动 创建静态 Pod 有两种方式配置文件和 HTTP 两种方式 静态 Pod 直接由特定节点上的kubelet进程来管理不通过 master 节点上的apiserver。无法与我们常用的控制器Deployment或者DaemonSet进行关联它由kubelet进程自己来监控当pod崩溃时重启该podkubelete也无法对他们进行健康检查。 静态 pod 始终绑定在某一个kubelet并且始终运行在同一个节点上。 kubelet会自动为每一个静态 pod 在 Kubernetes 的 apiserver 上创建一个镜像 PodMirror Pod因此我们可以在 apiserver 中查询到该 pod但是不能通过 apiserver 进行控制例如不能删除。 4.1 配置文件 配置文件就是放在特定目录下的标准的 JSON 或 YAML 格式的 pod 定义文件。用kubelet --pod-manifest-path来启动kubelet进程kubelet 定期的去扫描这个目录根据这个目录下出现或消失的 YAML/JSON 文件来创建或删除静态 pod。 比如我们在 node01 这个节点上用静态 pod 的方式来启动一个 nginx 的服务。我们登录到node01节点上面可以通过下面命令找到kubelet对应的启动配置文件 $ systemctl status kubelet配置文件路径为 $ /etc/systemd/system/kubelet.service.d/10-kubeadm.conf打开这个文件我们可以看到其中有一条如下的环境变量配置 EnvironmentKUBELET_SYSTEM_PODS_ARGS--pod-manifest-path/etc/kubernetes/manifests --allow-privilegedtrue所以如果我们通过kubeadm的方式来安装的集群环境(master节点)对应的kubelet已经配置了我们的静态 Pod 文件的路径那就是/etc/kubernetes/manifests所以我们只需要在该目录下面创建一个标准的 Pod 的 JSON 或者 YAML 文件即可; 如果你的 kubelet 启动参数中没有配置上面的–pod-manifest-path参数的话那么添加上这个参数然后重启 kubelet 即可。 [root node01 ~] $ cat EOF /etc/kubernetes/manifest/static-web.yaml apiVersion: v1 kind: Pod metadata:name: static-weblabels:app: static spec:containers:- name: webimage: nginxports:- name: webcontainerPort: 80 EOFmaster节点 node节点 4.2 通过 HTTP 创建静态 Pods kubelet 周期地从–manifest-url参数指定的地址下载文件并且把它翻译成 JSON/YAML 格式的 pod 定义。此后的操作方式与–pod-manifest-path相同kubelet 会不时地重新下载该文件当文件变化时对应地终止或启动静态 pod。 4.3 静态pods的动作行为 kubelet 启动时由–pod-manifest-path or --manifest-url参数指定的目录下定义的所有 pod 都会自动创建例如我们示例中的 static-web。 [rootnode01 ~] $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f6d05272b57e nginx:latest nginx 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c现在我们通过kubectl工具可以看到这里创建了一个新的镜像 Pod [rootnode01 ~] $ kubectl get pods NAME READY STATUS RESTARTS AGE static-web-my-node01 1/1 Running 0 2m静态 pod 的标签会传递给镜像 Pod可以用来过滤或筛选。 需要注意的是我们不能通过 API 服务器来删除静态 pod例如通过kubectl命令kebelet 不会删除它。 [rootnode01 ~] $ kubectl delete pod static-web-my-node01 [rootnode01 ~] $ kubectl get pods NAME READY STATUS RESTARTS AGE static-web-my-node01 1/1 Running 0 12s我们尝试手动终止容器可以看到kubelet很快就会自动重启容器。 [rootnode01 ~] $ docker ps CONTAINER ID IMAGE COMMAND CREATED ... 5b920cbaf8b1 nginx:latest nginx -g daemon of 2 seconds ago ...4.4 静态pods的动态增加和删除 运行中的kubelet周期扫描配置的目录我们这个例子中就是/etc/kubernetes/manifestsmaster节点下文件的变化当这个目录中有文件出现或消失时创建或删除pods。 [rootnode01 ~] $ mv /etc/kubernetes/manifests/static-web.yaml /tmp [rootnode01 ~] $ sleep 20 [rootnode01 ~] $ docker ps // no nginx container is running [rootnode01 ~] $ mv /tmp/static-web.yaml /etc/kubernetes/manifests [rootnode01 ~] $ sleep 20 [rootnode01 ~] $ docker ps CONTAINER ID IMAGE COMMAND CREATED ... e7a62e3427f1 nginx:latest nginx -g daemon of 27 seconds ago其实我们用 kubeadm 安装的集群master 节点上面的几个重要组件都是用静态 Pod 的方式运行的我们登录到 master 节点上查看/etc/kubernetes/manifests目录 [rootmaster ~]# ls /etc/kubernetes/manifests/ etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml 这些 Pod 都不会受到 apiserver 的控制.只能通过kubelet自己来进行控制这就是我们所说的静态 Pod。 5Pod Hook 所有资料在kubernetes-learning 实际上 Kubernetes 为我们的容器提供了生命周期钩子的就是我们说的Pod HookPod Hook 是由 kubelet 发起的当容器中的进程启动前或者容器中的进程终止之前运行这是包含在容器的生命周期之中。我们可以同时为 Pod 中的所有容器都配置 hook。 Kubernetes 为我们提供了两种钩子函数 PostStart这个钩子在容器创建后立即执行。但是并不能保证钩子将在容器ENTRYPOINT之前运行因为没有参数传递给处理程序。主要用于资源部署、环境准备等。不过需要注意的是如果钩子花费太长时间以至于不能运行或者挂起 容器将不能达到running状态。PreStop这个钩子在容器终止之前立即被调用。它是阻塞的意味着它是同步的 所以它必须在删除容器的调用发出之前完成。主要用于优雅关闭应用程序、通知其他系统等。如果钩子在执行期间挂起 Pod阶段将停留在running状态并且永不会达到failed状态。 如果PostStart或者PreStop钩子失败 它会杀死容器。所以我们应该让钩子函数尽可能的轻量。当然有些情况下长时间运行命令是合理的 比如在停止容器之前预先保存状态。 另外我们有两种方式来实现上面的钩子函数 Exec - 用于执行一段特定的命令不过要注意的是该命令消耗的资源会被计入容器。HTTP - 对容器上的特定的端点执行HTTP请求。 5.1环境准备 以下示例中定义了一个Nginx Pod其中设置了PostStart钩子函数即在容器创建成功后写入一句话到/usr/share/message文件中。 --- apiVersion: v1 kind: Pod metadata:name: hook-demo1labels:app: hook spec:containers:- name: hook-demo1image: nginxports:- name: webportcontainerPort: 80lifecycle:postStart:exec:command: [/bin/sh, -c, echo Hello from the postStart Handler /usr/share/message]创建 kubectl apply -f pod-hook1.yaml查看pod的详细信息 kubectl describe pod hook-demo1验证poststart hook需要进入到pod里面 kubectl exec hook-demo1 -i -t /bin/bash如果pod里面有多个container需要指定-c参数进入到特定的某个container里面 5.2优雅删除资源对象 当用户请求删除含有 pod 的资源对象时如Deployment等K8S 为了让应用程序优雅关闭即让应用程序完成正在处理的请求后再关闭软件K8S提供两种信息通知 默认K8S 通知 node 执行docker stop命令docker 会先向容器中PID为1的进程发送系统信号SIGTERM然后等待容器中的应用程序终止执行如果等待时间达到设定的超时时间或者默认超时时间30s会继续发送SIGKILL的系统信号强行 kill 掉进程。使用 pod 生命周期利用PreStop回调函数它执行在发送终止信号之前。 默认所有的优雅退出时间都在30秒内。kubectl delete 命令支持 --grace-period选项这个选项允许用户用他们自己指定的值覆盖默认值。 值’0’代表 强制删除 pod.在 kubectl 1.5 及以上的版本里执行强制删除时必须同时指定 --force --grace-period0。 kubectl delete pod hook-demo1 --grace-period0 --force强制删除一个 pod 是从集群状态还有 etcd 里立刻删除这个 pod。 当 Pod 被强制删除时 api 服务器不会等待来自 Pod 所在节点上的 kubelet 的确认信息pod 已经被终止。在 API 里 pod 会被立刻删除在节点上 pods 被设置成立刻终止后在强行杀掉前还会有一个很小的宽限期。 以下示例中定义了一个Nginx Pod其中设置了PreStop钩子函数即在容器退出之前优雅的关闭 Nginx: --- apiVersion: v1 kind: Pod metadata:name: hook-demo2labels:app: hook spec:containers:- name: hook-demo2image: nginxports:- name: webportcontainerPort: 80volumeMounts:- name: messagemountPath: /usr/sharelifecycle:preStop:exec:command: [/bin/sh, -c, echo Hello from the preStop Handler /usr/share/message]volumes:- name: messagehostPath:path: /tmp运行 kubectl apply -f pod-hook2.yaml删除 kubectl delete pod hook-demo2 或者 kubectl delete -f pod-hook2.yaml普通的node不会被调度到master上面所以可能需要到普通的node节点上去验证看/tmp/message是否存在 6 Pod健康检查 PostStart与PreStop其中PostStart是在容器创建后立即执行的而PreStop这个钩子函数则是在容器终止之前执行的 除了上面这两个钩子函数以外还有一项配置会影响到容器的生命周期的那就是健康检查的探针。 在Kubernetes集群当中我们可以通过配置liveness probe存活探针和readiness probe可读性探针来影响容器的生存周期。 kubelet 通过使用 liveness probe 来确定你的应用程序是否正在运行通俗点将就是是否还活着。一般来说如果你的程序一旦崩溃了 Kubernetes 就会立刻知道这个程序已经终止了然后就会重启这个程序。而我们的 liveness probe 的目的就是来捕获到当前应用程序还没有终止还没有崩溃如果出现了这些情况那么就重启处于该状态下的容器使应用程序在存在 bug 的情况下依然能够继续运行下去。 kubelet 使用 readiness probe 来确定容器是否已经就绪可以接收流量过来了。这个探针通俗点讲就是说是否准备好了现在可以开始工作了。只有当 Pod 中的容器都处于就绪状态的时候 kubelet 才会认定该 Pod 处于就绪状态因为一个 Pod 下面可能会有多个容器。当然 Pod 如果处于非就绪状态那么我们就会将他从我们的工作队列(实际上就是我们后面需要重点学习的 Service)中移除出来这样我们的流量就不会被路由到这个 Pod 里面来了。 和前面的钩子函数一样的我们这两个探针的支持两种配置方式 exec执行一段命令http检测某个 http 请求tcpSocket使用此配置 kubelet 将尝试在指定端口上打开容器的套接字。如果可以建立连接容器被认为是健康的如果不能就认为是失败的。实际上就是检查端口 6.1 livenessProbe:exec apiVersion: v1 kind: Pod metadata:name: liveness-execlabels:test: liveness spec:containers:- name: livenessimage: busyboxargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5运行 kubectl apply -f libeness-exec.yaml我们这里需要用到一个新的属性livenessProbe下面通过exec执行一段命令其中periodSeconds属性表示让kubelet每隔5秒执行一次存活探针也就是每5秒执行一次上面的cat /tmp/healthy命令如果命令执行成功了将返回0那么kubelet就会认为当前这个容器是存活的并且很监控如果返回的是非0值那么kubelet就会把该容器杀掉然后重启它。 另外一个属性initialDelaySeconds表示在第一次执行探针的时候要等待5秒这样能够确保我们的容器能够有足够的时间启动起来。 另外我们在容器启动的时候执行了如下命令 意思是说在容器最开始的30秒内有一个/tmp/healthy文件在这30秒内执行cat /tmp/healthy命令都会返回一个成功的返回码。30秒后我们删除这个文件现在执行cat /tmp/healthy是不是就会失败了这个时候就会重启容器了。 ~ /bin/sh -c touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600我们来创建下该Pod在30秒内查看Pod的Event 我们可以观察到容器是正常启动的在隔一会儿比如40s后再查看下Pod的Event在最下面有一条信息显示 liveness probe失败了容器被删掉并重新创建。然后通过kubectl get pod liveness-exec可以看到RESTARTS值加1了。 ~ kubectl describe pod liveness-exec6.2 livenessProbe:httpGet --- apiVersion: v1 kind: Pod metadata:name: liveness-httplabels:app: liveness spec:containers:- name: livenessimage: cnych/livenessargs:- /serverlivenessProbe:httpGet:path: /healthzport: 8080initialDelaySeconds: 3periodSeconds: 3 同样的根据periodSeconds属性我们可以知道kubelet需要每隔3秒执行一次liveness probe该探针将向容器中的 server 的8080端口发送一个 HTTP GET 请求。 如果 server 的 /healthz 路径的 handler 返回一个成功的返回码kubelet就会认定该容器是活着的并且很健康,如果返回失败的返回码kubelet将杀掉该容器并重启它。initialDelaySeconds 指定kubelet在该执行第一次探测之前需要等待3秒钟。 通常来说任何大于200小于400的返回码都会认定是成功的返回码。其他返回码都会被认为是失败的返回码。 http.HandleFunc(/healthz, func(w http.ResponseWriter, r *http.Request) {duration : time.Now().Sub(started)if duration.Seconds() 10 {w.WriteHeader(500)w.Write([]byte(fmt.Sprintf(error: %v, duration.Seconds())))} else {w.WriteHeader(200)w.Write([]byte(ok))} })大概意思就是最开始前10s返回状态码20010s过后就返回500的status_code了。所以当容器启动3秒后kubelet 开始执行健康检查。第一次健康监测会成功因为是在10s之内但是10秒后健康检查将失败因为现在返回的是一个错误的状态码了所以kubelet将会杀掉和重启容器。 同样的我们来创建下该Pod测试下效果10秒后查看 Pod 的 event确认liveness probe失败并重启了容器。 ~ kubectl describe pod liveness-http6.3 livenessProbe/readinessProbe:tcpSocket 过端口的方式来配置存活探针使用此配置kubelet将尝试在指定端口上打开容器的套接字。 如果可以建立连接容器被认为是健康的如果不能就认为是失败的。 --- apiVersion: v1 kind: Pod metadata:name: liveness-readinesslabels:app: liveness-readiness spec:containers:- name: liveness-readinessimage: cnych/livenessargs:- /serverlivenessProbe:httpGet:path: /healthzport: 8080initialDelaySeconds: 5periodSeconds: 5readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 3perioidSeconds: 3或者 apiVersion: v1 kind: Pod metadata:name: goproxylabels:app: goproxy spec:containers:- name: goproxyimage: cnych/goproxyports:- containerPort: 8080readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20TCP 检查的配置与 HTTP 检查非常相似只是将httpGet替换成了tcpSocket。 而且我们同时使用了readiness probe和liveness probe两种探针。 容器启动后5秒后kubelet将发送第一个readiness probe可读性探针。 该探针会去连接容器的8080端如果连接成功则该 Pod 将被标记为就绪状态。然后Kubelet将每隔10秒钟执行一次该检查。 liveness probe 容器启动15秒后kubelet将运行第一个 liveness probe。 就像readiness probe一样这将尝试去连接到容器的8080端口。如果liveness probe失败容器将重新启动。 有的时候应用程序可能暂时无法对外提供服务例如应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下您不想杀死应用程序也不想对外提供服务。 那么这个时候我们就可以使用readiness probe来检测和减轻这些情况。 Pod中的容器可以报告自己还没有准备不能处理Kubernetes服务发送过来的流量。 两者如果同时使用的话就可以确保流量不会到达还未准备好的容器准备好过后如果应用程序出现了错误则会重新启动容器。 另外除了上面的initialDelaySeconds和periodSeconds属性外探针还可以配置如下几个参数 timeoutSeconds探测超时时间默认1秒最小1秒。successThreshold探测失败后最少连续探测成功多少次才被认定为成功。默认是 1但是如果是liveness则必须是 1。最小值是 1。failureThreshold探测成功后最少连续探测失败多少次才被认定为失败。默认是 3最小值是 1。 7 初始化容器initContainers Init Container就是用来做初始化工作的容器可以是一个或者多个如果有多个的话这些容器会按定义的顺序依次执行只有所有的Init Container执行完后主容器才会被启动。我们知道一个Pod里面的所有容器是共享数据卷和网络命名空间的所以Init Container里面产生的数据可以被主容器使用到的。 从直观的角度看上去的话初始化容器的确有点像PreStart但是钩子函数和我们的Init Container是处在不同的阶段的我们可以通过下面的图来了解下 Init Container和钩子函数之类的区别: 从上面这张图我们可以直观的看到PostStart和PreStop包括liveness和readiness是属于主容器的生命周期范围内的而Init Container是独立于主容器之外的当然他们都属于Pod的生命周期范畴之内的 另外我们可以看到上面我们的Pod右边还有一个infra的容器这是一个什么容器呢 我们可以在集群环境中去查看下任意一个Pod对应的运行的Docker容器我们可以发现每一个Pod下面都包含了一个pause-amd64的镜像这个就是我们的infra镜像我们知道Pod下面的所有容器是共享同一个网络命名空间的这个镜像就是来做这个事情的所以每一个Pod当中都会包含一个这个镜像。 kubectl get pods pod-name -o yaml很多同学最开始 Pod 启动不起来就是因为这个 infra 镜像没有被拉下来因为默认该镜像是需要到谷歌服务器上拉取的所以需要提前拉取到节点上面 我们说Init Container主要是来做初始化容器工作的那么他有哪些应用场景呢 等待其他模块Ready这个可以用来解决服务之间的依赖问题比如我们有一个 Web 服务该服务又依赖于另外一个数据库服务但是在我们启动这个 Web 服务的时候我们并不能保证依赖的这个数据库服务就已经启动起来了所以可能会出现一段时间内 Web 服务连接数据库异常。要解决这个问题的话我们就可以在 Web 服务的 Pod 中使用一个 InitContainer在这个初始化容器中去检查数据库是否已经准备好了准备好了过后初始化容器就结束退出然后我们的主容器 Web 服务被启动起来这个时候去连接数据库就不会有问题了。做初始化配置比如集群里检测所有已经存在的成员节点为主容器准备好集群的配置信息这样主容器起来后就能用这个配置信息加入集群。其它场景如将 pod 注册到一个中央数据库、配置中心等。 演示下服务依赖的场景下初始化容器的使用方法如下Pod的定义方法 apiVersion: v1 kind: Pod metadata:name: init-pod1labels:app: init spec:containers:- name: init-containerimage: busyboxcommand: [sh, -c, echo The app is running! sleep 3600]initContainers:- name: init-myserviceimage: busyboxcommand: [sh, -c, until nslookup myservice; do echo waiting for myservice; sleep 2; done;]- name: init-mydbimage: busyboxcommand: [sh, -c, until nslookup mydb; do echo waiting for mydb; sleep 2; done;]--- apiVersion: v1 kind: Service metadata:name: myservice spec:ports:- protocol: TCPport: 80targetPort: 6379--- apiVersion: v1 kind: Service metadata:name: mydb spec:ports:- protocol: TCPport: 80targetPort: 6378Service的对应YAML内容 kubectl create -f initservice.yaml或者更新kubectl apply -f initservice.yaml查看service kubectl get svc等价于 kubectl get svc -n default我们可以先创建上面的Pod然后查看下Pod的状态然后再创建下面的Service对比下前后状态。 我们在Pod启动过程中初始化容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出。如果由于运行时或失败退出导致容器启动失败它会根据Pod的restartPolicy指定的策略进行重试。 然而如果 Pod 的 restartPolicy 设置为 AlwaysInit 容器失败时会使用 RestartPolicy 策略。 在所有的初始化容器没有成功之前Pod将不会变成 Ready状态。正在初始化中的Pod处于Pending状态但应该会将条件Initializing设置为 true。 接下来我们再来尝试创建一个做初始化配置工作的Pod --- apiVersion: v1 kind: Pod metadata:name: init-demolabels:app: init spec:initContainers:- name: installimage: busyboxcommand:- wget- -O- /work-dir/index.html- http://www.baidu.comvolumeMounts:- name: workdirmountPath: /work-dircontainers:- name: nginximage: nginxports:- containerPort: 80volumeMounts:- name: workdirmountPath: /usr/share/nginx/htmlvolumes:- name: workdiremptyDir: {} 我们可以看到这里又出现了volumes spec.volumes指的是Pod中的卷在host上spec.containers.volumeMounts是将指定的卷 mount 到容器指定的位置容器内相当于docker里面的-v 宿主机目录容器目录我们前面用到过hostPath我们这里使用的是emptyDir{}这个就相当于一个共享卷是一个临时的目录生命周期等同于Pod的生命周期。 初始化容器执行完会下载一个 html 文件映射到emptyDir{}而主容器也是和 spec.volumes 里的emptyDir{} 进行映射所以nginx容器的/usr/share/nginx/html目录下会映射 index.html 文件。 我们来创建下该Pod然后验证nginx容器是否运行: $ kubectl get pod init-demo输出显示了nginx容器正在运行 NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 43m在 init-demo 容器里的 nginx 容器打开一个 shell $ kubectl exec -it init-demo -- /bin/bash在Shell里直接查看下 index.html 的内容 rootnginx:~# cat /usr/share/nginx/html/index.html三、容器运行时 Containerd 1.查看当前k3s使用的容器运行时CRI ➜ ~ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME script-wang Ready control-plane,master 5d2h v1.28.8k3s1 192.168.70.221 none Ubuntu 20.04.6 LTS 5.15.150.1-microsoft-standard-WSL2 containerd://1.7.11-k3s2 ➜ ~ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME script-wang Ready control-plane,master 5d2h v1.28.8k3s1 192.168.70.221 none Ubuntu 20.04.6 LTS 5.15.150.1-microsoft-standard-WSL2 containerd://1.7.11-k3s22.K3S修改docker为运行环境 在缺省安装时K3S默认使用containerd作为容器运行环境 若想使用Docker环境替换containerd环境共有两种方法。 方法一安装时指定参数 在安装时通过环境变量INSTALL_K3S_EXEC curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC“server --docker” sh -s -或者 curl -sfL https://get.k3s.io | sh -s - server --docker 方法二安装后修改K3S服务的配置文件 vim /etc/systemd/system/multi-user.target.wants/k3s.service 文件内容如下 [Unit] DescriptionLightweight Kubernetes Documentationhttps://k3s.io Wantsnetwork-online.target[Install] WantedBymulti-user.target[Service] Typenotify EnvironmentFile/etc/systemd/system/k3s.service.env KillModeprocess Delegateyes # Having non-zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. LimitNOFILE1048576 LimitNPROCinfinity LimitCOREinfinity TasksMaxinfinity TimeoutStartSec0 Restartalways RestartSec5s ExecStartPre-/sbin/modprobe br_netfilter ExecStartPre-/sbin/modprobe overlay ExecStart/usr/local/bin/k3s server ~ ~ ~ /etc/systemd/system/multi-user.target.wants/k3s.service 26L, 670C 26,0-1 All 在这里我们需要修改ExecStart的值将其修改为 /usr/local/bin/k3s server --docker --no-deploy traefik 之后保存退出执行命令重新加载新的服务配置文件 systemctl daemon-reload 完成后重启K3S服务 systemctl restart k3s查询节点信息 显示docker则表示切换成功。 kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME iz2zeh0l1z8k2z5qifxbknz Ready master 177m v1.18.4k3s1 172.17.106.133 none CentOS Linux 7 (Core) 3.10.0-514.26.2.el7.x86_64 docker://19.3.12参考 10分钟搞定k8s中的helm和Chart从docker到k8s进阶Helm User Guide - Helm 用户指南Helm入门一篇就够了Helm 文档《从Docker到Kubernetes进阶课程》玩K8S不得不会的HELM什么是Helm它是如何提升云原生应用私有化部署效率的从Docker到Kubernetes进阶kubernetes-learning使用 Kubeadm 搭建集群环境完整版一文搞懂容器运行时 Containerd轻量级KubernetesK3S修改docker为运行环境
http://www.zqtcl.cn/news/60149/

相关文章:

  • 做药物分析必须知道的网站域名购买网站有哪些问题
  • 做站群的网站要备案吗半岛建设公司网站
  • 山西公司网站开发2018年网站建设
  • 购物平台排行榜2021南京网站seo找行者seo
  • 公司网站开发需要多少钱有深度的公司名字
  • 自建站跨境电商网站建设怎么让百度搜索到
  • php网站开发怎么接私活网站源码超市 下载
  • 坪山企业网站建设网站维护需要学什么
  • 重庆专业网站建设首页排名聊城找个人做网站
  • 威海做网站的公司有哪些vpswindows野外大全
  • 搜索引擎网站排名深圳婚纱摄影网站建设
  • 那个相亲网站做的比较好平面设计师如何做网站
  • 网站开发和前端是一样吗wordpress顺序
  • 无锡网站建设详细内容最近2018中文字幕免费看2019
  • 迪虎科技网站建设最有名的免费建站平台排行榜
  • 陕西网站建设厦门网站制作网站建设中系统实现
  • 西宁市营销网站建设公司怎么注册公司域名
  • 部署一个网站要做哪些工作平台页面设计
  • 福田网站建设团队青岛网站建设康之迅
  • 那里做网站比较好商丘网站建设制作
  • 怎么把做的网页放入网站宜昌市高新区建设局网站
  • jsp做的网站答辩问题网站怎么做不违法吗
  • 新浪博客怎样上传wordpresswap网站seo
  • iis html网站软件开发文档写作
  • 网站如何不需要备案网站做动态图片
  • 网站制作学校要的怎么做网站报告
  • 湖北省建设厅信息网站福州优化网站建设
  • 网站推广有什么方法wordpress 模板调用
  • 极客联盟网站建设公司怎么样wordpress 3.8.3 下载
  • php网站开发兼容怎么设置网站开发工具设备要求