<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Kubernetes on My Blog</title><link>/tags/kubernetes/</link><description>Recent content in Kubernetes on My Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 01 May 2022 00:00:00 +0000</lastBuildDate><atom:link href="/tags/kubernetes/index.xml" rel="self" type="application/rss+xml"/><item><title>Interactions between Pod priority and quality of service(Qos)</title><link>/2022/05/01/interactions-between-pod-priority-and-quality-of-serviceqos/</link><pubDate>Sun, 01 May 2022 00:00:00 +0000</pubDate><guid>/2022/05/01/interactions-between-pod-priority-and-quality-of-serviceqos/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="pod-优先级和服务质量之间的相互作用"&gt;Pod 优先级和服务质量之间的相互作用&lt;/h2&gt;
&lt;p&gt;集群中为了保障核心服务正常运行，有时候会舍弃掉不那么核心的服务。在通过Kubernetes实现的时候发现有两个手段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置pod的服务质量。Guaranteed, Burstable, BestEffort&lt;/li&gt;
&lt;li&gt;设置pod的优先级&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可是当这两个发生冲突的时候，优先考虑谁呢？比如现在这种情况：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;在资源不够用的情况下，一个高优先级，但是Qos属于Burstable或BestEffort的pod会抢占，低优先级但Qos属于Guaranteed的pod吗？
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;挠头不？&lt;/p&gt;
&lt;p&gt;进过查找资料，发现官方给出的答案是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img alt="01" loading="lazy" src="/2022/05/01/interactions-between-pod-priority-and-quality-of-serviceqos/01.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="02" loading="lazy" src="/2022/05/01/interactions-between-pod-priority-and-quality-of-serviceqos/02.png"&gt;&lt;/p&gt;
&lt;p&gt;其实这里是要分情况来看，简单来说是两个环节：&lt;strong&gt;pod调度环节&lt;/strong&gt; 和 &lt;strong&gt;节点压力驱逐环节&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="pod调度环节"&gt;pod调度环节&lt;/h3&gt;
&lt;p&gt;这里有最核心的一句话。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;The scheduler&amp;#39;s preemption logic does not consider QoS when choosing preemption targets.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;调度器的抢占逻辑在选择抢占目标时不考虑 QoS。只看pod的优先级，所以无论Guaranteed, Burstable, BestEffort，只要你的优先级最低，并且能腾出空间给新的pod运行，那很可能就是你了。&lt;/p&gt;
&lt;h3 id="节点压力驱逐环节"&gt;节点压力驱逐环节&lt;/h3&gt;
&lt;p&gt;而对于节点压力驱逐环节可能会繁琐一点&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;As a result, kubelet ranks and evicts pods in the following order:
BestEffort or Burstable pods where the usage exceeds requests. These pods are evicted based on their Priority and then by how much their usage level exceeds the request.
Guaranteed pods and Burstable pods where the usage is less than requests are evicted last, based on their Priority.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第一条：usage exceeds requests&lt;/p&gt;</description></item><item><title>kubernetes常见问题</title><link>/2021/05/01/kubernetes%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 01 May 2021 00:00:00 +0000</pubDate><guid>/2021/05/01/kubernetes%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="rancher平台使用问题记录"&gt;Rancher平台使用问题记录&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;平台问题&lt;/th&gt;
&lt;th style="text-align: left"&gt;详细说明&lt;/th&gt;
&lt;th style="text-align: left"&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;rancher与k8s&lt;br&gt;异常断连&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;br&gt;&lt;img alt="image" loading="lazy" src="/2021/05/01/kubernetes%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/image.png"&gt;&lt;br&gt;&lt;img alt="image-1" loading="lazy" src="/2021/05/01/kubernetes%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/image-1.png"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;1.在查看大量日志时出现过该问题&lt;br&gt;2.一些官方组织的交流群中建议优化 k8s系统参数，增加ip port range&lt;br&gt;&lt;br&gt;&lt;img alt="image-2" loading="lazy" src="/2021/05/01/kubernetes%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/image-2.png"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;k8s grpc-lb无效&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;方案有4种：&lt;br&gt;1、grpc-client + k8s headless&lt;br&gt;2、envoy (grpc proxy)&lt;br&gt;3、server mesh (istio/linkerd)&lt;br&gt;4、&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;rancher平台部署&lt;br&gt;节点亲和性&lt;br&gt;pod亲和性/反亲和性&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;删除deployment，对应service未删除&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;headless服务部署&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;节点选择/在页面打污点&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;k3s部署 指定reserve预留资源&lt;br&gt;agent 无法设置reserve？&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;a href="https://docs.rancher.cn/docs/k3s/installation/install-options/server-config/_index/#agent-%E7%BD%91%E7%BB%9C"&gt;https://docs.rancher.cn/docs/k3s/installation/install-options/server-config/_index/#agent-%E7%BD%91%E7%BB%9C&lt;/a&gt;&lt;br&gt;&lt;a href="https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/"&gt;https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;zoomkeeper更新pod始终有一个没有update&lt;/td&gt;
&lt;td style="text-align: left"&gt;rollingUpdatePartition: 0 即可&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions"&gt;https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Kafka部署extralaccess&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;longhorn storage 在etcd恢复中是否可用？&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;Kubernetes在在删除namespace后的恢复问题？&lt;/td&gt;
&lt;td style="text-align: left"&gt;1.通过etcd恢复所有的资源配置&lt;br /&gt;2.配置所有的storageclass创建pv的回收策略为：retain&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="开发人员使用需求汇总"&gt;开发人员使用需求汇总&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;需求内容&lt;/th&gt;
&lt;th style="text-align: left"&gt;详细说明&lt;/th&gt;
&lt;th style="text-align: left"&gt;时间&lt;/th&gt;
&lt;th style="text-align: left"&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;pod对cpu/memery资源可见性限制&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;pod支持绑定宿主机CPU核&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;api-gateway&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;nuclio pod 统一对外开放访问&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;有状态数据库服务更新手动确认&lt;/td&gt;
&lt;td style="text-align: left"&gt;更新要求：&lt;br /&gt;1.先只更新一个pod&lt;br /&gt;2.手动确认第一个pod运行正常之后再更新其他pod&lt;br /&gt;3.pod确认时间几分钟到数小时不等，无法使用readness进行确认&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions"&gt;https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="k3s-在混用dockercontainerd之后重启docker导致的pod-hostport模式中iptables路由混乱问题测试验证"&gt;k3s 在混用docker/containerd之后，重启docker导致的pod hostport模式中iptables路由混乱问题测试验证&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;hostport&lt;/strong&gt;添加分析&lt;/p&gt;</description></item><item><title>k3s 安装</title><link>/2021/04/01/k3s-%E5%AE%89%E8%A3%85/</link><pubDate>Thu, 01 Apr 2021 00:00:00 +0000</pubDate><guid>/2021/04/01/k3s-%E5%AE%89%E8%A3%85/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="k3s-简介"&gt;k3s 简介&lt;/h1&gt;
&lt;p&gt;K3s 是一个轻量级的 Kubernetes 发行版，它针对边缘计算、物联网等场景进行了高度优化。由于运行 K3s 所需的资源相对较少，所以 K3s 也适用于开发和测试场景。&lt;/p&gt;
&lt;p&gt;部署起来非常简单，所有服务打包为单个二进制文件，同时启动程序自动处理了众多TLS认证的内容，存储也是用轻量级数据库或者内置etcd等。&lt;/p&gt;
&lt;h1 id="k3s安装"&gt;k3s安装&lt;/h1&gt;
&lt;h2 id="第一个master"&gt;第一个master&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# first master&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;K3S_TOKEN&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;262c73d1ac2e7a8179c861a8a47640f8&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSTALL_K3S_EXEC&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;server --cluster-init&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSTALL_K3S_MIRROR&lt;span style="color:#f92672"&gt;=&lt;/span&gt;cn &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSTALL_K3S_VERSION&lt;span style="color:#f92672"&gt;=&lt;/span&gt;v1.20.4+k3s1 sh -s -
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# check&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl status k3s.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="第二个master"&gt;第二个master&lt;/h2&gt;
&lt;p&gt;只需要在第一个master的基础上，指定第一个master的IP &lt;code&gt;K3S_URL=&amp;quot;https://${first_master_ip}:6443&amp;quot;&lt;/code&gt; ，同时去掉初始化选项 &lt;code&gt;--cluster-init&lt;/code&gt; 即可。如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# other master&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;first_master_ip&lt;span style="color:#f92672"&gt;=&lt;/span&gt;172.26.186.176
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;K3S_TOKEN&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;262c73d1ac2e7a8179c861a8a47640f8&amp;#39;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;K3S_URL&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;first_master_ip&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;:6443&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSTALL_K3S_EXEC&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;server&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSTALL_K3S_MIRROR&lt;span style="color:#f92672"&gt;=&lt;/span&gt;cn &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;INSTALL_K3S_VERSION&lt;span style="color:#f92672"&gt;=&lt;/span&gt;v1.20.4+k3s1 sh -s -
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# check&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl status k3s.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl get nodes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="node节点"&gt;node节点&lt;/h2&gt;
&lt;p&gt;计算节点再去掉 &lt;code&gt;INSTALL_K3S_EXEC&lt;/code&gt; 参数，直接去加入集群即可&lt;/p&gt;</description></item><item><title>k8s学习笔记-26-kubeasz+ansible部署集群</title><link>/2018/10/05/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-26-kubeasz-ansible%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4/</link><pubDate>Fri, 05 Oct 2018 00:00:00 +0000</pubDate><guid>/2018/10/05/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-26-kubeasz-ansible%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;官方学习文档：https://github.com/easzlab/kubeasz&lt;/p&gt;
&lt;h1 id="1环境说明"&gt;1、环境说明&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;IP&lt;/th&gt;
&lt;th&gt;主机名&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;虚拟机配置&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;192.168.56.11&lt;/td&gt;
&lt;td&gt;k8s-master&lt;/td&gt;
&lt;td&gt;deploy、master1、lb1、etcd&lt;/td&gt;
&lt;td&gt;4c4g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192.168.56.12&lt;/td&gt;
&lt;td&gt;k8s-master2&lt;/td&gt;
&lt;td&gt;master2、lb2&lt;/td&gt;
&lt;td&gt;4c4g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192.168.56.13&lt;/td&gt;
&lt;td&gt;k8s-node01&lt;/td&gt;
&lt;td&gt;etcd、node&lt;/td&gt;
&lt;td&gt;2c2g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192.168.56.14&lt;/td&gt;
&lt;td&gt;k8s-node02&lt;/td&gt;
&lt;td&gt;etcd、node&lt;/td&gt;
&lt;td&gt;2c2g&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192.168.56.110&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;vip&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;系统内核&lt;/td&gt;
&lt;td&gt;3.10&lt;/td&gt;
&lt;td&gt;docker版本&lt;/td&gt;
&lt;td&gt;18.09&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;k8s版本&lt;/td&gt;
&lt;td&gt;1.13&lt;/td&gt;
&lt;td&gt;etcd版本&lt;/td&gt;
&lt;td&gt;3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="2准备工作"&gt;2、准备工作&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;四台机器，全部执行：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install -y epel-release
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum update -y
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install python -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;deploy节点安装ansible并配置密钥认证&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;yum install -y ansible
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh-keygen
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; ip in &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;12&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;13&lt;/span&gt; 14;&lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; ssh-copy-id 192.168.56.$ip;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;deploy节点编排K8S&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# git clone https://github.com/gjmzj/kubeasz.git&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# mv kubeasz/* /etc/ansible/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以根据自己所需版本，下载对应的tar包，这里我下载1.13
经过一番折腾，最终把k8s.1-13-5.tar.gz的tar包放到了depoly上&lt;/p&gt;</description></item><item><title>k8s学习笔记-25-Helm程序包管理器</title><link>/2018/09/25/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-25-helm%E7%A8%8B%E5%BA%8F%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8/</link><pubDate>Tue, 25 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/25/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-25-helm%E7%A8%8B%E5%BA%8F%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="1helm的概念和架构"&gt;1、Helm的概念和架构&lt;/h2&gt;
&lt;p&gt;每个成功的软件平台都有一个优秀的打包系统，比如 Debian、Ubuntu 的 apt，Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。&lt;/p&gt;
&lt;p&gt;**思考？？**Helm 到底解决了什么问题？为什么 Kubernetes 需要 Helm？&lt;/p&gt;
&lt;p&gt;Kubernetes 能够很好地组织和编排容器，但它缺少一个更高层次的应用打包工具，而 Helm 就是来干这件事的。&lt;/p&gt;
&lt;p&gt;举个例子，我们需要部署一个MySQL服务，Kubernetes则需要部署以下对象：&lt;/p&gt;
&lt;p&gt;① 为了能够让外界访问到MySQL，需要部署一个mysql的service；&lt;/p&gt;
&lt;p&gt;②需要进行定义MySQL的密码，则需要部署一个Secret；&lt;/p&gt;
&lt;p&gt;③Mysql的运行需要持久化的数据存储，此时还需要部署PVC；&lt;/p&gt;
&lt;p&gt;④保证后端mysql的运行，还需要部署一个Deployment，以支持以上的对象。&lt;/p&gt;
&lt;p&gt;针对以上对象，我们可以使用YAML文件进行定义并部署，但是仅仅对于单个的服务支持，如果应用需要由一个甚至几十个这样的服务组成，并且还需要考虑各种服务的依赖问题，可想而知，这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm，就是为了解决Kubernetes这种应用部署繁重的现象。&lt;/p&gt;
&lt;p&gt;Helm的核心术语：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chart：一个helm程序包，是创建一个应用的信息集合，包含各种Kubernetes对象的配置模板、参数定义、依赖关系、文档说明等。可以将Chart比喻为yum中的软件安装包；&lt;/li&gt;
&lt;li&gt;Repository：Charts仓库，用于集中存储和分发Charts；&lt;/li&gt;
&lt;li&gt;Config：应用程序实例化安装运行时所需要的配置信息；&lt;/li&gt;
&lt;li&gt;Release：特定的Chart部署于目标集群上的一个实例，代表这一个正在运行的应用。当chart被安装到Kubernetes集群，就会生成一个release，chart可以多次安装到同一个集群，每次安装都是一个release。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Helm的程序架构：&lt;/p&gt;
&lt;p&gt;Helm主要由Helm客户端、Tiller服务器和Charts仓库组成，如下图：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;helm：客户端，GO语言编写，实现管理本地的Chart仓库，可管理Chart，与Tiller服务进行交互，用于发送Chart，实例安装、查询、卸载等操作。&lt;/li&gt;
&lt;li&gt;Tiller：服务端，通常运行在K8S集群之上。用于接收helm发来的Charts和Conifg，合并生成release，完成部署。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简单的说：Helm 客户端负责管理 chart；Tiller 服务器负责管理 release。&lt;/p&gt;
&lt;h2 id="2部署helm"&gt;2、部署Helm&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://docs.helm.sh/using_helm/#quickstart-guide"&gt;helm部署文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Helm的部署方式有两种：预编译的二进制程序和源码编译安装，这里使用二进制的方式进行安装&lt;/p&gt;
&lt;h3 id="1下载helm"&gt;（1）下载helm&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz --no-check-certificate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# tar -xf helm-v2.9.1-linux-amd64.tar.gz &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master ~&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# cd linux-amd64/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master linux-amd64&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# ls&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;helm LICENSE README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master linux-amd64&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# mv helm /usr/bin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;root@k8s-master linux-amd64&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&lt;span style="color:#75715e"&gt;# helm version&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Client: &amp;amp;version.Version&lt;span style="color:#f92672"&gt;{&lt;/span&gt;SemVer:&lt;span style="color:#e6db74"&gt;&amp;#34;v2.9.1&amp;#34;&lt;/span&gt;, GitCommit:&lt;span style="color:#e6db74"&gt;&amp;#34;20adb27c7c5868466912eebdf6664e7390ebe710&amp;#34;&lt;/span&gt;, GitTreeState:&lt;span style="color:#e6db74"&gt;&amp;#34;clean&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2部署tiller"&gt;（2）部署Tiller&lt;/h3&gt;
&lt;p&gt;helm第一次init时，需要链接api-server并进行认证，所以在运行helm时，会去读取kube-config文件，所以必须确认当前用户存在kube-config文件。&lt;/p&gt;</description></item><item><title>k8s学习笔记-24-Prometheus监控</title><link>/2018/09/19/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-24-prometheus%E7%9B%91%E6%8E%A7/</link><pubDate>Wed, 19 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/19/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-24-prometheus%E7%9B%91%E6%8E%A7/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="1prometheus概述"&gt;1、Prometheus概述&lt;/h1&gt;
&lt;p&gt;除了前面的资源指标（如CPU、内存）以外，用户或管理员需要了解更多的指标数据，比如&lt;code&gt;Kubernetes&lt;/code&gt;指标、容器指标、节点资源指标以及应用程序指标等等。自定义指标API允许请求任意的指标，其指标API的实现要指定相应的后端监视系统。而&lt;code&gt;Prometheus&lt;/code&gt;是第一个开发了相应适配器的监控系统。这个适用于&lt;code&gt;Prometheus&lt;/code&gt;的&lt;code&gt;Kubernetes Customm Metrics Adapter&lt;/code&gt;是属于Github上的&lt;a href="https://github.com/DirectXMan12/k8s-prometheus-adapter"&gt;k8s-prometheus-adapter&lt;/a&gt;项目提供的。其原理图如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/19/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-24-prometheus%E7%9B%91%E6%8E%A7/1349539-20190323102150508-489908309.png"&gt;&lt;/p&gt;
&lt;p&gt;要知道的是&lt;code&gt;prometheus&lt;/code&gt;本身就是一监控系统，也分为&lt;code&gt;server&lt;/code&gt;端和&lt;code&gt;agent&lt;/code&gt;端，&lt;code&gt;server&lt;/code&gt;端从被监控主机获取数据，而&lt;code&gt;agent&lt;/code&gt;端需要部署一个&lt;code&gt;node_exporter&lt;/code&gt;，主要用于数据采集和暴露节点的数据，那么 在获取Pod级别或者是mysql等多种应用的数据，也是需要部署相关的&lt;code&gt;exporter&lt;/code&gt;。我们可以通过&lt;code&gt;PromQL&lt;/code&gt;的方式对数据进行查询，但是由于本身&lt;code&gt;prometheus&lt;/code&gt;属于第三方的 解决方案，原生的k8s系统并不能对&lt;code&gt;Prometheus&lt;/code&gt;的自定义指标进行解析，就需要借助于&lt;code&gt;k8s-prometheus-adapter&lt;/code&gt;将这些指标数据查询接口转换为标准的&lt;code&gt;Kubernetes&lt;/code&gt;自定义指标。&lt;/p&gt;
&lt;p&gt;Prometheus是一个开源的服务监控系统和时序数据库，其提供了通用的数据模型和快捷数据采集、存储和查询接口。它的核心组件Prometheus服务器定期从静态配置的监控目标或者基于服务发现自动配置的目标中进行拉取数据，新拉取到的数据大于配置的内存缓存区时，数据就会持久化到存储设备当中。Prometheus组件架构图如下：
&lt;img alt="img" loading="lazy" src="/2018/09/19/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-24-prometheus%E7%9B%91%E6%8E%A7/1349539-20190323104228352-317414087.png"&gt;&lt;/p&gt;
&lt;p&gt;如上图，每个被监控的主机都可以通过专用的&lt;code&gt;exporter&lt;/code&gt;程序提供输出监控数据的接口，并等待&lt;code&gt;Prometheus&lt;/code&gt;服务器周期性的进行数据抓取。如果存在告警规则，则抓取到数据之后会根据规则进行计算，满足告警条件则会生成告警，并发送到&lt;code&gt;Alertmanager&lt;/code&gt;完成告警的汇总和分发。当被监控的目标有主动推送数据的需求时，可以以&lt;code&gt;Pushgateway&lt;/code&gt;组件进行接收并临时存储数据，然后等待&lt;code&gt;Prometheus&lt;/code&gt;服务器完成数据的采集。&lt;/p&gt;
&lt;p&gt;任何被监控的目标都需要事先纳入到监控系统中才能进行时序数据采集、存储、告警和展示，监控目标可以通过配置信息以静态形式指定，也可以让Prometheus通过服务发现的机制进行动态管理。下面是组件的一些解析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;监控代理程序：如node_exporter：收集主机的指标数据，如平均负载、CPU、内存、磁盘、网络等等多个维度的指标数据。&lt;/li&gt;
&lt;li&gt;kubelet（cAdvisor）：收集容器指标数据，也是K8S的核心指标收集，每个容器的相关指标数据包括：CPU使用率、限额、文件系统读写限额、内存使用率和限额、网络报文发送、接收、丢弃速率等等。&lt;/li&gt;
&lt;li&gt;API Server：收集API Server的性能指标数据，包括控制队列的性能、请求速率和延迟时长等等&lt;/li&gt;
&lt;li&gt;etcd：收集etcd存储集群的相关指标数据&lt;/li&gt;
&lt;li&gt;kube-state-metrics：该组件可以派生出k8s相关的多个指标数据，主要是资源类型相关的计数器和元数据信息，包括制定类型的对象总数、资源限额、容器状态以及Pod资源标签系列等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prometheus 能够直接把 Kubernetes API Server作为服务发现系统使用进而动态发现和监控集群中的所有可被监控的对象。这里需要特别说明的是，Pod 资源需要添加下列注解信息才能被Prometheus 系统自动发现并抓取其内建的指标数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1） prometheus. io/ scrape： 用于 标识 是否 需要 被 采集 指标 数据， 布尔 型 值， true 或 false。&lt;/li&gt;
&lt;li&gt;2） prometheus. io/ path： 抓取 指标 数据 时 使用 的 URL 路径， 一般 为/ metrics。&lt;/li&gt;
&lt;li&gt;3） prometheus. io/ port： 抓取 指标 数据 时 使 用的 套 接 字 端口， 如 8080。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外， 仅 期望 Prometheus 为 后端 生成 自定义 指标 时 仅 部署 Prometheus 服务器 即可， 它 甚至 也不 需要 数据 持久 功能。 但 若要 配置 完整 功能 的 监控 系统， 管理员 还需 要在 每个 主机 上 部署 node_exporter、 按需部署其他特有类型的 exporter 以及Alertmanager。&lt;/p&gt;</description></item><item><title>k8s学习笔记-23-资源指标和集群监控</title><link>/2018/09/18/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-23-%E8%B5%84%E6%BA%90%E6%8C%87%E6%A0%87%E5%92%8C%E9%9B%86%E7%BE%A4%E7%9B%91%E6%8E%A7/</link><pubDate>Tue, 18 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/18/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-23-%E8%B5%84%E6%BA%90%E6%8C%87%E6%A0%87%E5%92%8C%E9%9B%86%E7%BE%A4%E7%9B%91%E6%8E%A7/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="1资源指标和资源监控"&gt;1、资源指标和资源监控&lt;/h1&gt;
&lt;p&gt;一个集群系统管理离不开监控，同样的Kubernetes也需要根据数据指标来采集相关数据，从而完成对集群系统的监控状况进行监测。这些指标总体上分为两个组成：监控集群本身和监控Pod对象，通常一个集群的衡量性指标包括以下几个部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;节点资源状态：主要包括网络带宽、磁盘空间、CPU和内存使用率&lt;/li&gt;
&lt;li&gt;节点的数量：即时性了解集群的可用节点数量可以为用户计算服务器使用的费用支出提供参考。&lt;/li&gt;
&lt;li&gt;运行的Pod对象：正在运行的Pod对象数量可以评估可用节点数量是否足够，以及节点故障时是否能平衡负载。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另一个方面，对Pod资源对象的监控需求大概有以下三类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes指标：监测特定应用程序相关的Pod对象的部署过程、副本数量、状态信息、健康状态、网络等等。&lt;/li&gt;
&lt;li&gt;容器指标：容器的资源需求、资源限制、CPU、内存、磁盘空间、网络带宽的实际占用情况。&lt;/li&gt;
&lt;li&gt;应用程序指标：应用程序自身的内建指标，和业务规则相关&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="2weave-scope监控集群"&gt;2、Weave Scope监控集群&lt;/h1&gt;
&lt;p&gt;Weave Scope 是 Docker 和 Kubernetes 可视化监控工具。Scope 提供了至上而下的集群基础设施和应用的完整视图，用户可以轻松对分布式的容器化应用进行实时监控和问题诊断。 对于复杂的应用编排和依赖关系，scope可以使用清晰的图标一览应用状态和拓扑关系。&lt;/p&gt;
&lt;h2 id="1weave-scope部署"&gt;（1）Weave Scope部署&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master mainfests]# kubectl apply -f &amp;#34;https://cloud.weave.works/k8s/scope.yaml?k8s-version=$(kubectl version | base64 | tr -d &amp;#39;\n&amp;#39;)&amp;#34;
namespace/weave created #创建名称空间weave，也可以在创建时指定名称空间
serviceaccount/weave-scope created #创建serviceaccount
clusterrole.rbac.authorization.k8s.io/weave-scope created
clusterrolebinding.rbac.authorization.k8s.io/weave-scope created
deployment.apps/weave-scope-app created #创建deployment
service/weave-scope-app created #创建service
daemonset.extensions/weave-scope-agent created #创建deamonset
[root@k8s-master mainfests]# kubectl get ns
NAME STATUS AGE
default Active 68d
ingress-nginx Active 28d
kube-public Active 68d
kube-system Active 68d
weave Active 1m
[root@k8s-master mainfests]# kubectl get deployment -n weave
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
weave-scope-app 1 1 1 1 1m
[root@k8s-master mainfests]# kubectl get svc -n weave
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
weave-scope-app ClusterIP 10.97.229.215 &amp;lt;none&amp;gt; 80/TCP 33s
[root@k8s-master mainfests]# kubectl get pod -n weave
NAME READY STATUS RESTARTS AGE
weave-scope-agent-5876w 1/1 Running 0 1m
weave-scope-agent-d6jgt 1/1 Running 0 1m
weave-scope-agent-t9p5g 1/1 Running 0 1m
weave-scope-app-578556559-nfxrf 1/1 Running 0 1m
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;DaemonSet weave-scope-agent，集群每个节点上都会运行的 scope agent 程序，负责收集数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Deployment &lt;code&gt;weave-scope-app&lt;/code&gt;，scope 应用，从 agent 获取数据，通过 Web UI 展示并与用户交互。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Service &lt;code&gt;weave-scope-app&lt;/code&gt;，默认是 ClusterIP 类型，为了方便已通过 &lt;code&gt;kubectl edit&lt;/code&gt; 修改为 &lt;code&gt;NodePort&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master mainfests]# kubectl edit svc/weave-scope-app -n weave
将service的type改为NodePort
service/weave-scope-app edited
[root@k8s-master mainfests]# kubectl get svc -n weave
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
weave-scope-app NodePort 10.97.229.215 &amp;lt;none&amp;gt; 80:32313/TCP 11m
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="2使用-scope"&gt;（2）使用 Scope&lt;/h2&gt;
&lt;p&gt;浏览器访问 &lt;code&gt;http://192.168.56.11:32313/&lt;/code&gt;，Scope 默认显示当前所有的 Controller（Deployment、DaemonSet 等）。&lt;/p&gt;</description></item><item><title>k8s学习笔记-20-K8S组件运行原理详解总结</title><link>/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/</link><pubDate>Sat, 15 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="一看图说k8s"&gt;一、看图说K8S&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;先从一张大图来观看一下K8S是如何运作的，再具体去细化K8S的概念、组件以及网络模型。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/1349539-20190307152625497-1629030475.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;从上图，我们可以看到K8S组件和逻辑及其复杂，但是这并不可怕，我们从宏观上先了解K8S是怎么用的，再进行庖丁解牛。从上图我们可以看出：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kubernetes集群主要由Master和Node两类节点组成&lt;/li&gt;
&lt;li&gt;Master的组件包括：apiserver、controller-manager、scheduler和etcd等几个组件，其中apiserver是整个集群的网关。&lt;/li&gt;
&lt;li&gt;Node主要由kubelet、kube-proxy、docker引擎等组件组成。kubelet是K8S集群的工作与节点上的代理组件。&lt;/li&gt;
&lt;li&gt;一个完整的K8S集群，还包括CoreDNS、Prometheus（或HeapSter）、Dashboard、Ingress Controller等几个附加组件。其中cAdivsor组件作用于各个节点（master和node节点）之上，用于收集及收集容器及节点的CPU、内存以及磁盘资源的利用率指标数据，这些统计数据由Heapster聚合后，可以通过apiserver访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;要了解K8S的所有组件，没去走一遍，永远不知道它是怎么跑起来的，那么下面就带着几个新手疑问来看K8S&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1、K8S是如何对容器编排？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;在K8S集群中，容器并非最小的单位，K8S集群中最小的调度单位是Pod，容器则被封装在Pod之中。由此可知，一个容器或多个容器可以同属于在一个Pod之中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2、Pod是怎么创建出来的？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Pod并不是无缘无故跑出来的，它是一个抽象的l逻辑概念，那么Pod是如何创建的呢？Pod是由Pod控制器进行管理控制，其代表性的Pod控制器有Deployment、StatefulSet等。这里我们先有这样的一个概念，后面再详细解刨。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;3、Pod资源组成的应用如何提供外部访问的？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Pod组成的应用是通过Service这类抽象资源提供内部和外部访问的，但是service的外部访问需要端口的映射，带来的是端口映射的麻烦和操作的繁琐。为此还有一种提供外部访问的资源叫做Ingress。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;4、Service又是怎么关联到Pod呢？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;在上面说的Pod是由Pod控制器进行管理控制，对Pod资源对象的期望状态进行自动管理。而在Pod控制器是通过一个YAML的文件进行定义Pod资源对象的。在该文件中，还会对Pod资源对象进行打标签，用于Pod的辨识，而Servcie就是通过标签选择器，关联至同一标签类型的Pod资源对象。这样就实现了从service&amp;ndash;&amp;gt;pod&amp;ndash;&amp;gt;container的一个过程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;5、Pod的怎么创建逻辑流程是怎样的？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;（1）客户端提交创建请求，可以通过API Server的Restful API，也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。&lt;/li&gt;
&lt;li&gt;（2）API Server处理用户请求，存储Pod数据到etcd。&lt;/li&gt;
&lt;li&gt;（3）调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。&lt;/li&gt;
&lt;li&gt;（4）过滤主机 (调度预选)：调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量，那么可用资源比Pod需要的资源量少的主机会被过滤掉。&lt;/li&gt;
&lt;li&gt;（5）主机打分(调度优选)：对第一步筛选出的符合要求的主机进行打分，在主机打分阶段，调度器会考虑一些整体优化策略，比如把容一个Replication Controller的副本分布到不同的主机上，使用最低负载的主机等。&lt;/li&gt;
&lt;li&gt;（6）选择主机：选择打分最高的主机，进行binding操作，结果存储到etcd中。&lt;/li&gt;
&lt;li&gt;（7）kubelet根据调度结果执行Pod创建操作： 绑定成功后，scheduler会调用APIServer的API在etcd中创建一个boundpod对象，描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息，一旦发现应该在该工作节点上运行的boundpod对象没有更新，则调用Docker API创建并启动pod内的容器。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;从上面的几个疑问，大致了解了K8S怎么工作的，那么现在再从三个面去了解Kubernetes，分别是Kubernetes概念和术语、集群组件、网络模型。&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id="二k8s的概念和术语"&gt;二、K8S的概念和术语&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Kubernetes是利用共享网络将多个物理机或者虚拟机组成一个集群，在各个服务器之间进行通信，该集群是配置Kubernetes的所有租金啊啊、功能和负载的物理平台。&lt;/p&gt;
&lt;p&gt;一个Kubernetes集群由master和node组成。如下图：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Master：是集群的网关和中枢枢纽，主要作用：暴露API接口，跟踪其他服务器的健康状态、以最优方式调度负载，以及编排其他组件之间的通信。单个的Master节点可以完成所有的功能，但是考虑单点故障的痛点，生产环境中通常要部署多个Master节点，组成Cluster。&lt;/li&gt;
&lt;li&gt;Node：是Kubernetes的工作节点，负责接收来自Master的工作指令，并根据指令相应地创建和销毁Pod对象，以及调整网络规则进行合理路由和流量转发。生产环境中，Node节点可以有N个。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/1349539-20180706110354540-513539099.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kubernetes从宏观上看分为2个角色：Master和Node，但是在Master节点和Node节点上都存在着多个组件来支持内部的业务逻辑，其包括：运行应用、应用编排、服务暴露、应用恢复等等，在Kubernetes中这些概念被抽象为Pod、Service、Controller等资源类型。先来了解一下这些常用概念和术语：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;（1）Pod&lt;/p&gt;
&lt;p&gt;从上图，我们可以看到K8S并不直接地运行容器，而是被一个抽象的资源对象&amp;ndash;Pod所封装，它是K8S最小的调度单位。这里要注意的是，Pod可以封装一个活多个容器！同一个Pod中共享网络名称空间和存储资源，而容器之间可以通过本地回环接口：lo 直接通信，但是彼此之间又在Mount、User和Pid等名称空间上保持了隔离。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;（2）资源标签（Label）&lt;/p&gt;
&lt;p&gt;标签（Label）是将资源进行分类的标识符，就好像超市的商品分类一般。资源标签具体化的就是一个键值型（key/values)数据，相信了解redis的友友应该知道什么是键值数据。使用标签是为了对指定对象进行辨识，比如Pod对象。标签可以在对象创建时进行附加，也可以创建后进行添加或修改。要知道的是一个对象可以有多个标签，一个标签页可以附加到多个对象。如图：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/1349539-20190119113920669-1808345614.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;（3）标签选择器（Selector）&lt;/p&gt;
&lt;p&gt;有标签，当然就有标签选择器，它是根据Label进行过滤符合条件的资源对象的一种 机制。比如将含有标签&lt;code&gt;role: backend&lt;/code&gt;的所有Pod对象挑选出来归并为一组。通常在使用过程中，会通过标签对资源对象进行分类，然后再通过标签选择器进行筛选，最常见的应用就是讲一组这样的Pod资源对象创建为某个Service的端点。如图：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/1349539-20190119113954245-190016216.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;（4）Pod控制器（Controller）&lt;/p&gt;
&lt;p&gt;虽然Pod是K8S的最小调度单位，但是K8S并不会直接地部署和管理Pod对象，而是要借助于另外一个抽象资源&amp;ndash;Controller进行管理。其实一种管理Pod生命周期的资源抽象，并且它是一类对象，并非单个的资源对象，其中包括：ReplicationController、ReplicaSet、Deployment、StatefulSet、Job等。&lt;/p&gt;
&lt;p&gt;以Deployment为例，它负责确保定义的Pod对象的副本数量符合预期的设置，这样用户只需要声明应用的期望状态，控制器就会自动地对其进行管理。如图：&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-20-k8s%E7%BB%84%E4%BB%B6%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3%E6%80%BB%E7%BB%93/1349539-20190119114016205-1879336161.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;（5）服务资源（Service）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Service是建立在一组Pod对象之上的资源对象，在前面提过，它是通过标签选择器选择一组Pod对象，并为这组Pod对象定义一个统一的固定访问入口（通常是一个IP地址），如果K8S存在DNS附件（如coredns）它就会在Service创建时为它自动配置一个DNS名称，用于客户端进行服务发现。&lt;/p&gt;
&lt;p&gt;通常我们直接请求Service IP，该请求就会被负载均衡到后端的端点，即各个Pod对象，从这点上，是不是有点像负载均衡器呢，因此Service本质上是一个4层的代理服务，另外Service还可以将集群外部流量引入至集群，这就需要节点对Service的端口进行映射了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（6）存储卷（Volume）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在使用容器时，我们知道，当数据存放于容器之中，容器销毁后，数据也会随之丢失。这就是需要一个外部存储，以保证数据的持久化存储。而存储卷就是这样的一个东西。&lt;/p&gt;
&lt;p&gt;存储卷（Volume）是独立于容器文件系统之外的存储空间，常用于扩展容器的存储空间并为其提供持久存储能力。存储卷在K8S中的分类为：临时卷、本地卷和网络卷。临时卷和本地卷都位于Node本地，一旦Pod被调度至其他Node节点，此类型的存储卷将无法被访问，因为临时卷和本地卷通常用于数据缓存，持久化的数据通常放置于持久卷（persistent volume）之中。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;（7）Name和Namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;名称（Name）是K8S集群中资源对象的标识符，通常作用于名称空间（Namespace），因此名称空间是名称的额外的限定机制。在同一个名称空间中，同一类型资源对象的名称必须具有唯一性。&lt;/p&gt;</description></item><item><title>k8s学习笔记-22-Pod资源调度</title><link>/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-22-pod%E8%B5%84%E6%BA%90%E8%B0%83%E5%BA%A6/</link><pubDate>Sat, 15 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-22-pod%E8%B5%84%E6%BA%90%E8%B0%83%E5%BA%A6/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;API Server在接受客户端提交Pod对象创建请求后，然后是通过调度器（kube-schedule）从集群中选择一个可用的最佳节点来创建并运行Pod。而这一个创建Pod对象，在调度的过程当中有3个阶段：节点预选、节点优选、节点选定，从而筛选出最佳的节点。如图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-22-pod%E8%B5%84%E6%BA%90%E8%B0%83%E5%BA%A6/1349539-20190315110744164-1442880527.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;节点预选：基于一系列的预选规则对每个节点进行检查，将那些不符合条件的节点过滤，从而完成节点的预选&lt;/li&gt;
&lt;li&gt;节点优选：对预选出的节点进行优先级排序，以便选出最合适运行Pod对象的节点&lt;/li&gt;
&lt;li&gt;节点选定：从优先级排序结果中挑选出优先级最高的节点运行Pod，当这类节点多于1个时，则进行随机选择&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当我们有需求要将某些Pod资源运行在特定的节点上时，我们可以通过组合节点标签，以及Pod标签或标签选择器来匹配特定的预选策略并完成调度，如&lt;code&gt;MatchInterPodAfinity、MatchNodeSelector、PodToleratesNodeTaints&lt;/code&gt;等预选策略，这些策略常用于为用户提供自定义Pod亲和性或反亲和性、节点亲和性以及基于污点及容忍度的调度机制。&lt;/p&gt;
&lt;h1 id="1常用的预选策略"&gt;1、常用的预选策略&lt;/h1&gt;
&lt;p&gt;预选策略实际上就是节点过滤器，例如节点标签必须能够匹配到Pod资源的标签选择器（MatchNodeSelector实现的规则），以及Pod容器的资源请求量不能大于节点上剩余的可分配资源（PodFitsResource规则）等等。执行预选操作，调度器会逐一根据规则进行筛选，如果预选没能选定一个合适的节点，此时Pod会一直处于Pending状态，直到有一个可用节点完成调度。其常用的预选策略如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CheckNodeCondition：检查是否可以在节点报告磁盘、网络不可用或未准备好的情况下将Pod对象调度其上。&lt;/li&gt;
&lt;li&gt;HostName：如果Pod对象拥有spec.hostname属性，则检查节点名称字符串是否和该属性值匹配。&lt;/li&gt;
&lt;li&gt;PodFitsHostPorts：如果Pod对象定义了ports.hostPort属性，则检查Pod指定的端口是否已经被节点上的其他容器或服务占用。&lt;/li&gt;
&lt;li&gt;MatchNodeSelector：如果Pod对象定义了spec.nodeSelector属性，则检查节点标签是否和该属性匹配。&lt;/li&gt;
&lt;li&gt;NoDiskConflict：检查Pod对象请求的存储卷在该节点上可用。&lt;/li&gt;
&lt;li&gt;PodFitsResources：检查节点上的资源（CPU、内存）可用性是否满足Pod对象的运行需求。&lt;/li&gt;
&lt;li&gt;PodToleratesNodeTaints：如果Pod对象中定义了spec.tolerations属性，则需要检查该属性值是否可以接纳节点定义的污点（taints）。&lt;/li&gt;
&lt;li&gt;PodToleratesNodeNoExecuteTaints：如果Pod对象定义了spec.tolerations属性，检查该属性是否接纳节点的NoExecute类型的污点。&lt;/li&gt;
&lt;li&gt;CheckNodeLabelPresence：仅检查节点上指定的所有标签的存在性，要检查的标签以及其可否存在取决于用户的定义。&lt;/li&gt;
&lt;li&gt;CheckServiceAffinity：根据当前Pod对象所属的Service已有其他Pod对象所运行的节点调度，目前是将相同的Service的Pod对象放在同一个或同一类节点上。&lt;/li&gt;
&lt;li&gt;MaxEBSVolumeCount：检查节点上是否已挂载EBS存储卷数量是否超过了设置的最大值，默认值：39&lt;/li&gt;
&lt;li&gt;MaxGCEPDVolumeCount：检查节点上已挂载的GCE PD存储卷是否超过了设置的最大值，默认值：16&lt;/li&gt;
&lt;li&gt;MaxAzureDiskVolumeCount：检查节点上已挂载的Azure Disk存储卷数量是否超过了设置的最大值，默认值：16&lt;/li&gt;
&lt;li&gt;CheckVolumeBinding：检查节点上已绑定和未绑定的PVC是否满足Pod对象的存储卷需求。&lt;/li&gt;
&lt;li&gt;NoVolumeZoneConflct：在给定了区域限制的前提下，检查在该节点上部署Pod对象是否存在存储卷冲突。&lt;/li&gt;
&lt;li&gt;CheckNodeMemoryPressure：在给定了节点已经上报了存在内存资源压力过大的状态，则需要检查该Pod是否可以调度到该节点上。&lt;/li&gt;
&lt;li&gt;CheckNodePIDPressure：如果给定的节点已经报告了存在PID资源压力过大的状态，则需要检查该Pod是否可以调度到该节点上。&lt;/li&gt;
&lt;li&gt;CheckNodeDiskPressure：如果给定的节点存在磁盘资源压力过大，则检查该Pod对象是否可以调度到该节点上。&lt;/li&gt;
&lt;li&gt;MatchInterPodAffinity：检查给定的节点能否可以满足Pod对象的亲和性和反亲和性条件，用来实现Pod亲和性调度或反亲和性调度。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在上面的这些预选策略里面，CheckNodeLabelPressure和CheckServiceAffinity可以在预选过程中结合用户自定义调度逻辑，这些策略叫做可配置策略。其他不接受参数进行自定义配置的称为静态策略。&lt;/p&gt;
&lt;h1 id="2优选函数"&gt;2、优选函数&lt;/h1&gt;
&lt;p&gt;预选策略筛选出一个节点列表就会进入优选阶段，在这个过程调度器会向每个通过预选的节点传递一系列的优选函数来计算其优先级分值，优先级分值介于0-10之间，其中0表示不适用，10表示最适合托管该Pod对象。&lt;/p&gt;
&lt;p&gt;另外，调度器还支持给每个优选函数指定一个简单的值，表示权重，进行节点优先级分值计算时，它首先将每个优选函数的计算得分乘以权重，然后再将所有优选函数的得分相加，从而得出节点的最终优先级分值。权重可以让管理员定义优选函数倾向性的能力，其计算优先级的得分公式如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;finalScoreNode = (weight1 * priorityFunc1) + (weight2 * priorityFunc2) + ......
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下图是关于优选函数的列表图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-22-pod%E8%B5%84%E6%BA%90%E8%B0%83%E5%BA%A6/1349539-20190315110812120-2048644331.png"&gt;&lt;/p&gt;
&lt;h1 id="3节点亲和调度"&gt;3、节点亲和调度&lt;/h1&gt;
&lt;p&gt;节点亲和性是用来确定Pod对象调度到哪一个节点的规则，这些规则基于节点上的自定义标签和Pod对象上指定的标签选择器进行定义。&lt;/p&gt;
&lt;p&gt;定义节点亲和性规则有2种：硬亲和性（require）和软亲和性（preferred）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;硬亲和性：实现的是强制性规则，是Pod调度时必须满足的规则，否则Pod对象的状态会一直是Pending&lt;/li&gt;
&lt;li&gt;软亲和性：实现的是一种柔性调度限制，在Pod调度时可以尽量满足其规则，在无法满足规则时，可以调度到一个不匹配规则的节点之上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;定义节点亲和规则的两个要点：一是节点配置是否合乎需求的标签，而是Pod对象定义合理的标签选择器，这样才能够基于标签选择出期望的目标节点。&lt;/p&gt;
&lt;p&gt;需要注意的是&lt;code&gt;preferredDuringSchedulingIgnoredDuringExecution&lt;/code&gt;和&lt;code&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/code&gt;名字中后半段字符串&lt;code&gt;IgnoredDuringExecution&lt;/code&gt;表示的是，在Pod资源基于节点亲和性规则调度到某个节点之后，如果节点的标签发生了改变，调度器不会讲Pod对象从该节点上移除，因为该规则仅对新建的Pod对象有效。&lt;/p&gt;
&lt;h2 id="31节点硬亲和性"&gt;3.1、节点硬亲和性&lt;/h2&gt;
&lt;p&gt;下面的配置清单中定义的Pod对象，使用节点硬亲和性和规则定义将当前Pod调度到标签为zone=foo的节点上：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
name: with-require-nodeaffinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: zone,operator: In,values: [&amp;#34;foo&amp;#34;]}
containers:
- name: myapp
image: ikubernetes/myapp:v1
#创建Pod对象
[root@k8s-master ~]# kubectl apply -f require-nodeAffinity-pod.yaml
pod/with-require-nodeaffinity created
#由于集群中并没有节点含有节点标签为zone=foo，所以创建的Pod一直处于Pending状态
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity
NAME READY STATUS RESTARTS AGE
with-require-nodeaffinity 0/1 Pending 0 35s
#查看Pending具体的原因
[root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 3s (x21 over 1m) default-scheduler 0/3 nodes are available: 3 node(s) didn&amp;#39;t match node selector.
#给node01节点打上zone=foo的标签，可以看到成功调度到node01节点上
[root@k8s-master ~]# kubectl label node k8s-node01 zone=foo
node/k8s-node01 labeled
[root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 58s (x25 over 2m) default-scheduler 0/3 nodes are available: 3 node(s) didn&amp;#39;t match node selector.
Normal Pulled 4s kubelet, k8s-node01 Container image &amp;#34;ikubernetes/myapp:v1&amp;#34; already present on machine
Normal Created 4s kubelet, k8s-node01 Created container
Normal Started 4s kubelet, k8s-node01 Started container
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity -o wide
NAME READY STATUS RESTARTS AGE IP NODE
with-require-nodeaffinity 1/1 Running 0 6m 10.244.1.12 k8s-node01
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在定义节点亲和性时，&lt;code&gt;requiredDuringSchedulingIgnoredDuringExecution&lt;/code&gt;字段的值是一个对象列表，用于定义节点硬亲和性，它可以由一个或多个&lt;code&gt;nodeSelectorTerms&lt;/code&gt;定义的对象组成，此时值需要满足其中一个&lt;code&gt;nodeSelectorTerms&lt;/code&gt;即可。&lt;/p&gt;</description></item><item><title>k8s学习笔记-21-k8s的网络模型和网络策略</title><link>/2018/09/12/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-21-k8s%E7%9A%84%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B%E5%92%8C%E7%BD%91%E7%BB%9C%E7%AD%96%E7%95%A5/</link><pubDate>Wed, 12 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/12/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-21-k8s%E7%9A%84%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B%E5%92%8C%E7%BD%91%E7%BB%9C%E7%AD%96%E7%95%A5/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="1kubernetes网络模型和cni插件"&gt;1、Kubernetes网络模型和CNI插件&lt;/h1&gt;
&lt;p&gt;在Kubernetes中设计了一种网络模型，要求无论容器运行在集群中的哪个节点，所有容器都能通过一个扁平的网络平面进行通信，即在同一IP网络中。需要注意的是：在K8S集群中，IP地址分配是以Pod对象为单位，而非容器，同一Pod内的所有容器共享同一网络名称空间。&lt;/p&gt;
&lt;h2 id="11docker网络模型"&gt;1.1、Docker网络模型&lt;/h2&gt;
&lt;p&gt;了解Docker的友友们都应该清楚，Docker容器的原生网络模型主要有3种：Bridge（桥接）、Host（主机）、none。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bridge：借助虚拟网桥设备为容器建立网络连接。&lt;/li&gt;
&lt;li&gt;Host：设置容器直接共享当前节点主机的网络名称空间。&lt;/li&gt;
&lt;li&gt;none：多个容器共享同一个网络名称空间。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#使用以下命令查看docker原生的三种网络
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0efec019c899 bridge bridge local
40add8bb5f07 host host local
ad94f0b1cca6 none null local
#none网络，在该网络下的容器仅有lo网卡，属于封闭式网络，通常用于对安全性要求较高并且不需要联网的应用
[root@localhost ~]# docker run -it --network=none busybox
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
#host网络，共享宿主机的网络名称空间，容器网络配置和host一致，但是存在端口冲突的问题
[root@localhost ~]# docker run -it --network=host busybox
/ # ip addr
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:0c:29:69:a7:23 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 84129sec preferred_lft 84129sec
inet6 fe80::20c:29ff:fe69:a723/64 scope link
valid_lft forever preferred_lft forever
3: docker0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue
link/ether 02:42:29:09:8f:dd brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:29ff:fe09:8fdd/64 scope link
valid_lft forever preferred_lft forever
/ # hostname
localhost
#bridge网络，Docker安装完成时会创建一个名为docker0的linux bridge，不指定网络时，创建的网络默认为桥接网络，都会桥接到docker0上。
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024229098fdd no
[root@localhost ~]# docker run -d nginx #运行一个nginx容器
c760a1b6c9891c02c992972d10a99639d4816c4160d633f1c5076292855bbf2b
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024229098fdd no veth3f1b114
一个新的网络接口veth3f1b114桥接到了docker0上，veth3f1b114就是新创建的容器的虚拟网卡。进入容器查看其网络配置：
[root@localhost ~]# docker exec -it c760a1b6c98 bash
root@c760a1b6c989:/# apt-get update
root@c760a1b6c989:/# apt-get iproute
root@c760a1b6c989:/# ip a
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
38: eth0@if39: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;从上可以看到容器内有一个网卡&lt;code&gt;eth0@if39&lt;/code&gt;，实际上&lt;code&gt;eth0@if39&lt;/code&gt;和&lt;code&gt;veth3f1b114&lt;/code&gt;是一对&lt;code&gt;veth pair&lt;/code&gt;。&lt;code&gt;veth pair&lt;/code&gt;是一种成对出现的特殊网络设备，可以想象它们由一根虚拟的网线进行连接的一对网卡，&lt;code&gt;eth0@if39&lt;/code&gt;在容器中，&lt;code&gt;veth3f1b114&lt;/code&gt;挂在网桥&lt;code&gt;docker0&lt;/code&gt;上，最终的效果就是&lt;code&gt;eth0@if39&lt;/code&gt;也挂在了&lt;code&gt;docker0上&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>k8s学习笔记-19-Kubernetes dashboard认证访问</title><link>/2018/09/10/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-19-kubernetes-dashboard%E8%AE%A4%E8%AF%81%E8%AE%BF%E9%97%AE/</link><pubDate>Mon, 10 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/10/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-19-kubernetes-dashboard%E8%AE%A4%E8%AF%81%E8%AE%BF%E9%97%AE/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;Dashboard:https://github.com/kubernetes/dashboard&lt;/p&gt;
&lt;h2 id="一dashboard部署"&gt;一、Dashboard部署&lt;/h2&gt;
&lt;p&gt;由于需要用到k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0，这里有2种方式进行pull 镜像。docker search该镜像名称，直接pull，再重新进行tag；另外一种方式是通过谷歌容器镜像拉取。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-node01 ~]# docker pull siriuszg/kubernetes-dashboard-amd64
[root@k8s-node01 ~]# docker tag siriuszg/kubernetes-dashboard-amd64:latest k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
或者是
[root@k8s-node01 ~]# docker pull mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;再看其部署的过程：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret/kubernetes-dashboard-certs created
serviceaccount/kubernetes-dashboard created
role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
deployment.apps/kubernetes-dashboard created
service/kubernetes-dashboard created
[root@k8s-master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-78fcdf6894-nmcmz 1/1 Running 1 54d
coredns-78fcdf6894-p5pfm 1/1 Running 1 54d
etcd-k8s-master 1/1 Running 2 54d
kube-apiserver-k8s-master 1/1 Running 9 54d
kube-controller-manager-k8s-master 1/1 Running 5 54d
kube-flannel-ds-n5c86 1/1 Running 1 54d
kube-flannel-ds-nrcw2 1/1 Running 1 52d
kube-flannel-ds-pgpr7 1/1 Running 5 54d
kube-proxy-glzth 1/1 Running 1 52d
kube-proxy-rxlt7 1/1 Running 2 54d
kube-proxy-vxckf 1/1 Running 4 54d
kube-scheduler-k8s-master 1/1 Running 3 54d
kubernetes-dashboard-767dc7d4d-n4clq 1/1 Running 0 3s
[root@k8s-master ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 &amp;lt;none&amp;gt; 53/UDP,53/TCP 54d
kubernetes-dashboard ClusterIP 10.105.204.4 &amp;lt;none&amp;gt; 443/TCP 30m
[root@k8s-master ~]# kubectl patch svc kubernetes-dashboard -p &amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;type&amp;#34;:&amp;#34;NodePort&amp;#34;}}&amp;#39; -n kube-system #以打补丁方式修改dasboard的访问方式
service/kubernetes-dashboard patched
[root@k8s-master ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 &amp;lt;none&amp;gt; 53/UDP,53/TCP 54d
kubernetes-dashboard NodePort 10.105.204.4 &amp;lt;none&amp;gt; 443:32645/TCP 31m
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;浏览器访问：https://192.168.56.12:32645，如图：&lt;strong&gt;这里需要注意的是谷歌浏览器会禁止不安全证书访问，建议使用火狐浏览器，并且需要在高级选项中添加信任&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>k8s学习笔记-18-认证、授权和准入控制</title><link>/2018/09/08/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-18-%E8%AE%A4%E8%AF%81%E6%8E%88%E6%9D%83%E5%92%8C%E5%87%86%E5%85%A5%E6%8E%A7%E5%88%B6/</link><pubDate>Sat, 08 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/08/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-18-%E8%AE%A4%E8%AF%81%E6%8E%88%E6%9D%83%E5%92%8C%E5%87%86%E5%85%A5%E6%8E%A7%E5%88%B6/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;API Server作为Kubernetes网关，是访问和管理资源对象的唯一入口，其各种集群组件访问资源都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验，其中包括身份验证、操作权限验证以及操作规范验证等，需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。如下图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/08/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-18-%E8%AE%A4%E8%AF%81%E6%8E%88%E6%9D%83%E5%92%8C%E5%87%86%E5%85%A5%E6%8E%A7%E5%88%B6/1349539-20190307160125484-1365856991.png"&gt;&lt;/p&gt;
&lt;h2 id="一serviceaccount"&gt;一、ServiceAccount&lt;/h2&gt;
&lt;p&gt;Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的。它与User account不同&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User account是为人设计的，而service account则是为Pod中的进程调用Kubernetes API而设计；&lt;/li&gt;
&lt;li&gt;User account是跨namespace的，而service account则是仅局限它所在的namespace；&lt;/li&gt;
&lt;li&gt;每个namespace都会自动创建一个default service account&lt;/li&gt;
&lt;li&gt;Token controller检测service account的创建，并为它们创建&lt;a href="https://www.kubernetes.org.cn/secret"&gt;secret&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;开启ServiceAccount Admission Controller后
&lt;ul&gt;
&lt;li&gt;每个Pod在创建后都会自动设置spec.serviceAccount为default（除非指定了其他ServiceAccout）&lt;/li&gt;
&lt;li&gt;验证Pod引用的service account已经存在，否则拒绝创建&lt;/li&gt;
&lt;li&gt;如果Pod没有指定ImagePullSecrets，则把service account的ImagePullSecrets加到Pod中&lt;/li&gt;
&lt;li&gt;每个container启动后都会挂载该service account的token和ca.crt到/var/run/secrets/kubernetes.io/serviceaccount/&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当创建 pod 的时候，如果没有指定一个 service account，系统会自动在与该pod 相同的 namespace 下为其指派一个default service account。而pod和apiserver之间进行通信的账号，称为serviceAccountName。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
filebeat-ds-hxgdx 1/1 Running 1 34d
filebeat-ds-s466l 1/1 Running 2 34d
myapp-0 1/1 Running 0 3h
myapp-1 1/1 Running 0 3h
myapp-2 1/1 Running 0 4h
myapp-3 1/1 Running 0 4h
pod-vol-demo 2/2 Running 0 2d
redis-5b5d6fbbbd-q8ppz 1/1 Running 1 2d
[root@k8s-master ~]# kubectl get pods/myapp-0 -o yaml |grep &amp;#34;serviceAccountName&amp;#34;
serviceAccountName: default
[root@k8s-master ~]# kubectl describe pods myapp-0
Name: myapp-0
Namespace: default
......
Volumes:
......
default-token-j5pf5:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-j5pf5
Optional: false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;从上面可以看到每个Pod无论定义与否都会有个存储卷，这个存储卷为default-token-*** token令牌，这就是pod和serviceaccount认证信息。通过secret进行定义，由于认证信息属于敏感信息，所以需要保存在secret资源当中，并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver，并完成认证。每个 namespace 中都有一个默认的叫做 default 的 service account 资源。进行查看名称空间内的secret，也可以看到对应的default-token。让当前名称空间中所有的pod在连接apiserver时可以使用的预制认证信息，从而保证pod之间的通信。&lt;/p&gt;</description></item><item><title>k8s学习笔记-17-statefulset控制器</title><link>/2018/09/03/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-17-statefulset%E6%8E%A7%E5%88%B6%E5%99%A8/</link><pubDate>Mon, 03 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/03/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-17-statefulset%E6%8E%A7%E5%88%B6%E5%99%A8/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="一statefulset简介"&gt;一、statefulset简介&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;    从前面的学习我们知道使用Deployment创建的pod是无状态的，当挂载了Volume之后，如果该pod挂了，Replication Controller会再启动一个pod来保证可用性，但是由于pod是无状态的，pod挂了就会和之前的Volume的关系断开，新创建的Pod无法找到之前的Pod。但是对于用户而言，他们对底层的Pod挂了是没有感知的，但是当Pod挂了之后就无法再使用之前挂载的存储卷。&lt;/p&gt;
&lt;p&gt;    为了解决这一问题，就引入了StatefulSet用于保留Pod的状态信息。&lt;/p&gt;
&lt;p&gt;    StatefulSet是为了解决有状态服务的问题（对应Deployments和ReplicaSets是为无状态服务而设计），其应用场景包括：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;1、稳定的持久化存储，即Pod重新调度后还是能访问到相同的持久化数据，基于PVC来实现&lt;/li&gt;
&lt;li&gt;2、稳定的网络标志，即Pod重新调度后其PodName和HostName不变，基于Headless Service（即没有Cluster IP的Service）来实现&lt;/li&gt;
&lt;li&gt;3、有序部署，有序扩展，即Pod是有顺序的，在部署或者扩展的时候要依据定义的顺序依次依次进行（即从0到N-1，在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态），基于init containers来实现&lt;/li&gt;
&lt;li&gt;4、有序收缩，有序删除（即从N-1到0）&lt;/li&gt;
&lt;li&gt;5、有序的滚动更新&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;从上面的应用场景可以发现，StatefulSet由以下几个部分组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Headless Service（无头服务）用于为Pod资源标识符生成可解析的DNS记录。&lt;/li&gt;
&lt;li&gt;volumeClaimTemplates （存储卷申请模板）基于静态或动态PV供给方式为Pod资源提供专有的固定存储。&lt;/li&gt;
&lt;li&gt;StatefulSet，用于管控Pod资源。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1 id="二为什么要有headless"&gt;二、为什么要有headless？？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;    在deployment中，每一个pod是没有名称，是随机字符串，是无序的。而statefulset中是要求有序的，每一个pod的名称必须是固定的。当节点挂了，重建之后的标识符是不变的，每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符，必须保证其标识符的稳定并且唯一。
    为了实现标识符的稳定，这时候就需要一个headless service 解析直达到pod，还需要给pod配置一个唯一的名称。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="三为什么要-有volumeclaintemplate"&gt;三、为什么要 有volumeClainTemplate？？&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;    大部分有状态副本集都会用到持久存储，比如分布式系统来说，由于数据是不一样的，每个节点都需要自己专用的存储节点。而在deployment中pod模板中创建的存储卷是一个共享的存储卷，多个pod使用同一个存储卷，而statefulset定义中的每一个pod都不能使用同一个存储卷，由此基于pod模板创建pod是不适应的，这就需要引入volumeClainTemplate，当在使用statefulset创建pod时，会自动生成一个PVC，从而请求绑定一个PV，从而有自己专用的存储卷。Pod名称、PVC和PV关系图如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="1349539-20190307152625497-1629030475" loading="lazy" src="/2018/09/03/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-17-statefulset%E6%8E%A7%E5%88%B6%E5%99%A8/1349539-20190307152625497-1629030475.png"&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="四statefulset使用演示"&gt;四、statefulSet使用演示&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;在创建StatefulSet之前需要准备的东西，值得注意的是创建顺序非常关键，创建顺序如下：
1、Volume
2、Persistent Volume
3、Persistent Volume Claim
4、Service
5、StatefulSet
Volume可以有很多种类型，比如nfs、glusterfs等，我们这里使用的ceph RBD来创建。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="1查看statefulset的定义"&gt;（1）查看statefulset的定义&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl explain statefulset
KIND: StatefulSet
VERSION: apps/v1
DESCRIPTION:
StatefulSet represents a set of pods with consistent identities. Identities
are defined as: - Network: A single stable DNS and hostname. - Storage: As
many VolumeClaims as requested. The StatefulSet guarantees that a given
network identity will always map to the same storage identity.
FIELDS:
apiVersion &amp;lt;string&amp;gt;
kind &amp;lt;string&amp;gt;
metadata &amp;lt;Object&amp;gt;
spec &amp;lt;Object&amp;gt;
status &amp;lt;Object&amp;gt;
[root@k8s-master ~]# kubectl explain statefulset.spec
KIND: StatefulSet
VERSION: apps/v1
RESOURCE: spec &amp;lt;Object&amp;gt;
DESCRIPTION:
Spec defines the desired identities of pods in this set.
A StatefulSetSpec is the specification of a StatefulSet.
FIELDS:
podManagementPolicy &amp;lt;string&amp;gt; #Pod管理策略
replicas &amp;lt;integer&amp;gt; #副本数量
revisionHistoryLimit &amp;lt;integer&amp;gt; #历史版本限制
selector &amp;lt;Object&amp;gt; -required- #选择器，必选项
serviceName &amp;lt;string&amp;gt; -required- #服务名称，必选项
template &amp;lt;Object&amp;gt; -required- #模板，必选项
updateStrategy &amp;lt;Object&amp;gt; #更新策略
volumeClaimTemplates &amp;lt;[]Object&amp;gt; #存储卷申请模板，列表对象形式
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="2清单定义statefulset"&gt;（2）清单定义StatefulSet&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;如上所述，一个完整的StatefulSet控制器由一个Headless Service、一个StatefulSet和一个volumeClaimTemplate组成。如下资源清单中的定义：&lt;/p&gt;</description></item><item><title>k8s学习笔记-16-存储卷</title><link>/2018/09/02/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-16-%E5%AD%98%E5%82%A8%E5%8D%B7/</link><pubDate>Sun, 02 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/02/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-16-%E5%AD%98%E5%82%A8%E5%8D%B7/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="一存储卷的概念和类型"&gt;一、存储卷的概念和类型&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;为了保证数据的持久性，必须保证数据在外部存储在&lt;code&gt;docker&lt;/code&gt;容器中，为了实现数据的持久性存储，在宿主机和容器内做映射，可以保证在容器的生命周期结束，数据依旧可以实现持久性存储。但是在&lt;code&gt;k8s&lt;/code&gt;中，由于&lt;code&gt;pod&lt;/code&gt;分布在各个不同的节点之上，并不能实现不同节点之间持久性数据的共享，并且，在节点故障时，可能会导致数据的永久性丢失。为此，&lt;code&gt;k8s&lt;/code&gt;就引入了外部存储卷的功能。
k8s的存储卷类型：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl explain pod.spec.volumes #查看k8s支持的存储类型
KIND: Pod
VERSION: v1
常用分类：
emptyDir（临时目录）:Pod删除，数据也会被清除，这种存储成为emptyDir，用于数据的临时存储。
hostPath(宿主机目录映射):
本地的SAN(iSCSI,FC)、NAS(nfs,cifs,http)存储
分布式存储（glusterfs，rbd，cephfs）
云存储（EBS，Azure Disk）
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;persistentVolumeClaim &amp;ndash;&amp;gt;PVC(存储卷创建申请)
当你需要创建一个存储卷时，只需要进行申请对应的存储空间即可使用，这就是PVC。其关联关系如图：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/02/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-16-%E5%AD%98%E5%82%A8%E5%8D%B7/1349539-20181009150238161-243800675.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上图解析：在Pod上定义一个PVC，该PVC要关联到当前名称空间的PVC资源，该PVC只是一个申请，PVC需要和PV进行关联。PV属于存储上的一部分存储空间。但是该方案存在的问题是，我们无法知道用户是什么时候去创建Pod，也不知道创建Pod时定义多大的PVC，那么如何实现按需创建呢？？？&lt;/p&gt;
&lt;p&gt;不需要PV层，把所有存储空间抽象出来，这一个抽象层称为存储类，当用户创建PVC需要用到PV时，可以向存储类申请对应的存储空间，存储类会按照需求创建对应的存储空间，这就是PV的动态供给，如图：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/02/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-16-%E5%AD%98%E5%82%A8%E5%8D%B7/1349539-20181009150251762-2029671134.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;那么PV的动态供给，其重点是在存储类的定义，其分类大概是对存储的性能进行分类的，如图：金存储类、银存储类、铜存储类等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/09/02/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-16-%E5%AD%98%E5%82%A8%E5%8D%B7/1349539-20181009150328995-1548599425.png"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;总结：
k8s要使用存储卷，需要2步：
1、在pod定义volume，并指明关联到哪个存储设备
2、在容器使用volume mount进行挂载&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id="二emptydir存储卷演示"&gt;二、emptyDir存储卷演示&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;一个emptyDir 第一次创建是在一个pod被指定到具体node的时候，并且会一直存在在pod的生命周期当中，正如它的名字一样，它初始化是一个空的目录，pod中的容器都可以读写这个目录，这个目录可以被挂在到各个容器相同或者不相同的的路径下。当一个pod因为任何原因被移除的时候，这些数据会被永久删除。注意：一个容器崩溃了不会导致数据的丢失，因为容器的崩溃并不移除pod.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;emptyDir 磁盘的作用：
（1）普通空间，基于磁盘的数据存储
（2）作为从崩溃中恢复的备份点
（3）存储那些那些需要长久保存的数据，例web服务中的数据
默认的，emptyDir 磁盘会存储在主机所使用的媒介上，可能是SSD，或者网络硬盘，这主要取决于你的环境。当然，我们也可以将emptyDir.medium的值设置为Memory来告诉Kubernetes 来挂在一个基于内存的目录tmpfs，因为
tmpfs速度会比硬盘块度了，但是，当主机重启的时候所有的数据都会丢失。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl explain pods.spec.volumes.emptyDir #查看emptyDir存储定义
[root@k8s-master ~]# kubectl explain pods.spec.containers.volumeMounts #查看容器挂载方式
[root@k8s-master ~]# cd mainfests &amp;amp;&amp;amp; mkdir volumes &amp;amp;&amp;amp; cd volumes
[root@k8s-master volumes]# cp ../pod-demo.yaml ./
[root@k8s-master volumes]# mv pod-demo.yaml pod-vol-demo.yaml
[root@k8s-master volumes]# vim pod-vol-demo.yaml #创建emptyDir的清单
apiVersion: v1
kind: Pod
metadata:
name: pod-demo
namespace: default
labels:
app: myapp
tier: frontend
annotations:
magedu.com/create-by:&amp;#34;cluster admin&amp;#34;
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
volumeMounts: #在容器内定义挂载存储名称和挂载路径
- name: html
mountPath: /usr/share/nginx/html/
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- name: html
mountPath: /data/ #在容器内定义挂载存储名称和挂载路径
command: [&amp;#39;/bin/sh&amp;#39;,&amp;#39;-c&amp;#39;,&amp;#39;while true;do echo $(date) &amp;gt;&amp;gt; /data/index.html;sleep 2;done&amp;#39;]
volumes: #定义存储卷
- name: html #定义存储卷名称
emptyDir: {} #定义存储卷类型
[root@k8s-master volumes]# kubectl apply -f pod-vol-demo.yaml
pod/pod-vol-demo created
[root@k8s-master volumes]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-vol-demo 2/2 Running 0 27s
[root@k8s-master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
......
pod-vol-demo 2/2 Running 0 16s 10.244.2.34 k8s-node02
......
在上面，我们定义了2个容器，其中一个容器是输入日期到index.html中，然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。如下访问验证:
[root@k8s-master volumes]# curl 10.244.2.34 #访问验证
Tue Oct 9 03:56:53 UTC 2018
Tue Oct 9 03:56:55 UTC 2018
Tue Oct 9 03:56:57 UTC 2018
Tue Oct 9 03:56:59 UTC 2018
Tue Oct 9 03:57:01 UTC 2018
Tue Oct 9 03:57:03 UTC 2018
Tue Oct 9 03:57:05 UTC 2018
Tue Oct 9 03:57:07 UTC 2018
Tue Oct 9 03:57:09 UTC 2018
Tue Oct 9 03:57:11 UTC 2018
Tue Oct 9 03:57:13 UTC 2018
Tue Oct 9 03:57:15 UTC 2018
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="三hostpath存储卷演示"&gt;三、hostPath存储卷演示&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;hostPath宿主机路径，就是把pod所在的宿主机之上的脱离pod中的容器名称空间的之外的宿主机的文件系统的某一目录和pod建立关联关系，在pod删除时，存储数据不会丢失。&lt;/p&gt;</description></item><item><title>k8s学习笔记-15-Ingress和Ingress Controller</title><link>/2018/09/01/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-15-ingress%E5%92%8Cingress-controller/</link><pubDate>Sat, 01 Sep 2018 00:00:00 +0000</pubDate><guid>/2018/09/01/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-15-ingress%E5%92%8Cingress-controller/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h3 id="一什么是ingress"&gt;一、什么是Ingress？&lt;/h3&gt;
&lt;p&gt;从前面的学习，我们可以了解到&lt;code&gt;Kubernetes&lt;/code&gt;暴露服务的方式目前只有三种：&lt;code&gt;LoadBlancer Service、ExternalName、NodePort Service、Ingress&lt;/code&gt;；而我们需要将集群内服务提供外界访问就会产生以下几个问题：&lt;/p&gt;
&lt;h4 id="1pod-漂移问题"&gt;1、Pod 漂移问题&lt;/h4&gt;
&lt;p&gt;Kubernetes 具有强大的副本控制能力，能保证在任意副本（Pod）挂掉时自动从其他机器启动一个新的，还可以动态扩容等，通俗地说，这个 Pod 可能在任何时刻出现在任何节点上，也可能在任何时刻死在任何节点上；那么自然随着 Pod 的创建和销毁，Pod IP 肯定会动态变化；那么如何把这个动态的 Pod IP 暴露出去？这里借助于 Kubernetes 的 Service 机制，Service 可以以标签的形式选定一组带有指定标签的 Pod，并监控和自动负载他们的 Pod IP，那么我们向外暴露只暴露 Service IP 就行了；这就是 NodePort 模式：即在每个节点上开起一个端口，然后转发到内部 Pod IP 上，如下图所示：
此时的访问方式：&lt;a href="http://nodeip/"&gt;http://nodeip&lt;/a&gt;:nodeport/
&lt;img alt="img" loading="lazy" src="/2018/09/01/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-15-ingress%E5%92%8Cingress-controller/1349539-20180929174515031-619898952.png"&gt;&lt;/p&gt;
&lt;h4 id="2端口管理问题"&gt;2、端口管理问题&lt;/h4&gt;
&lt;p&gt;采用 NodePort 方式暴露服务面临问题是，服务一旦多起来，NodePort 在每个节点上开启的端口会及其庞大，而且难以维护；这时，我们可以能否使用一个Nginx直接对内进行转发呢？众所周知的是，Pod与Pod之间是可以互相通信的，而Pod是可以共享宿主机的网络名称空间的，也就是说当在共享网络名称空间时，Pod上所监听的就是Node上的端口。那么这又该如何实现呢？简单的实现就是使用 DaemonSet 在每个 Node 上监听 80，然后写好规则，因为 Nginx 外面绑定了宿主机 80 端口（就像 NodePort），本身又在集群内，那么向后直接转发到相应 Service IP 就行了，如下图所示：
&lt;img alt="img" loading="lazy" src="/2018/09/01/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-15-ingress%E5%92%8Cingress-controller/1349539-20180929175905911-113975562.png"&gt;&lt;/p&gt;
&lt;h4 id="3域名分配及动态更新问题"&gt;3、域名分配及动态更新问题&lt;/h4&gt;
&lt;p&gt;从上面的方法，采用 Nginx-Pod 似乎已经解决了问题，但是其实这里面有一个很大缺陷：当每次有新服务加入又该如何修改 Nginx 配置呢？？我们知道使用Nginx可以通过虚拟主机域名进行区分不同的服务，而每个服务通过upstream进行定义不同的负载均衡池，再加上location进行负载均衡的反向代理，在日常使用中只需要修改nginx.conf即可实现，那在K8S中又该如何实现这种方式的调度呢？？？&lt;/p&gt;
&lt;p&gt;假设后端的服务初始服务只有ecshop，后面增加了bbs和member服务，那么又该如何将这2个服务加入到Nginx-Pod进行调度呢？总不能每次手动改或者Rolling Update 前端 Nginx Pod 吧！！此时 Ingress 出现了，如果不算上面的Nginx，Ingress 包含两大组件：Ingress Controller 和 Ingress。
&lt;img alt="img" loading="lazy" src="/2018/09/01/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-15-ingress%E5%92%8Cingress-controller/1349539-20180930094041632-683389969.png"&gt;&lt;/p&gt;</description></item><item><title>k8s学习笔记-13-Pod控制器--DaemonSet</title><link>/2018/08/29/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-13-pod%E6%8E%A7%E5%88%B6%E5%99%A8--daemonset/</link><pubDate>Wed, 29 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/29/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-13-pod%E6%8E%A7%E5%88%B6%E5%99%A8--daemonset/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一什么是daemonset"&gt;一、什么是DaemonSet？&lt;/h2&gt;
&lt;p&gt;DaemonSet 确保全部（或者一些）Node 上运行一个 Pod 的副本。当有 Node 加入集群时，也会为他们新增一个 Pod 。当有 Node 从集群移除时，这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。&lt;/p&gt;
&lt;p&gt;使用 DaemonSet 的一些典型用法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;运行集群存储 daemon，例如在每个 Node 上运行 &lt;code&gt;glusterd&lt;/code&gt;、&lt;code&gt;ceph&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在每个 Node 上运行日志收集 daemon，例如&lt;code&gt;fluentd&lt;/code&gt;、&lt;code&gt;logstash&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在每个 Node 上运行监控 daemon，例如 &lt;a href="https://github.com/prometheus/node_exporter"&gt;Prometheus Node Exporter&lt;/a&gt;、&lt;code&gt;collectd&lt;/code&gt;、Datadog 代理、New Relic 代理，或 Ganglia &lt;code&gt;gmond&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个简单的用法是，在所有的 Node 上都存在一个 DaemonSet，将被作为每种类型的 daemon 使用。 一个稍微复杂的用法可能是，对单独的每种类型的 daemon 使用多个 DaemonSet，但具有不同的标志，和/或对不同硬件类型具有不同的内存、CPU要求。&lt;/p&gt;
&lt;h2 id="二编写daemonset-spec"&gt;二、编写DaemonSet Spec&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;（1）必需字段&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;和其它所有 Kubernetes 配置一样，DaemonSet 需要 &lt;code&gt;apiVersion&lt;/code&gt;、&lt;code&gt;kind&lt;/code&gt; 和 &lt;code&gt;metadata&lt;/code&gt;字段。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl explain daemonset
KIND: DaemonSet
VERSION: extensions/v1beta1
DESCRIPTION:
DEPRECATED - This group version of DaemonSet is deprecated by
apps/v1beta2/DaemonSet. See the release notes for more information.
DaemonSet represents the configuration of a daemon set.
FIELDS:
apiVersion &amp;lt;string&amp;gt;
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
kind &amp;lt;string&amp;gt;
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
metadata &amp;lt;Object&amp;gt;
Standard object&amp;#39;s metadata. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
spec &amp;lt;Object&amp;gt;
The desired behavior of this daemon set. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
status &amp;lt;Object&amp;gt;
The current status of this daemon set. This data may be out of date by some
window of time. Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;（2）Pod模板&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>k8s学习笔记-14-服务发现Service</title><link>/2018/08/29/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-14-%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0service/</link><pubDate>Wed, 29 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/29/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-14-%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0service/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一service的概念"&gt;一、Service的概念&lt;/h2&gt;
&lt;p&gt;　　运行在Pod中的应用是向客户端提供服务的守护进程，比如，nginx、tomcat、etcd等等，它们都是受控于控制器的资源对象，存在生命周期，我们知道Pod资源对象在自愿或非自愿终端后，只能被重构的Pod对象所替代，属于不可再生类组件。而在动态和弹性的管理模式下，Service为该类Pod对象提供了一个固定、统一的访问接口和负载均衡能力。&lt;/p&gt;
&lt;p&gt;　　其实，就是说Pod存在生命周期，有销毁，有重建，无法提供一个固定的访问接口给客户端。并且为了同类的Pod都能够实现工作负载的价值，由此Service资源出现了，可以为一类Pod资源对象提供一个固定的访问接口和负载均衡，类似于阿里云的负载均衡或者是LVS的功能。&lt;/p&gt;
&lt;p&gt;　　但是要知道的是，Service和Pod对象的IP地址，一个是虚拟地址，一个是Pod IP地址，都仅仅在集群内部可以进行访问，无法接入集群外部流量。而为了解决该类问题的办法可以是在单一的节点上做端口暴露（hostPort）以及让Pod资源共享工作节点的网络名称空间（hostNetwork）以外，还可以使用NodePort或者是LoadBalancer类型的Service资源，或者是有7层负载均衡能力的Ingress资源。&lt;/p&gt;
&lt;p&gt;　　Service是Kubernetes的核心资源类型之一，Service资源基于标签选择器将一组Pod定义成一个逻辑组合，并通过自己的IP地址和端口调度代理请求到组内的Pod对象，如下图所示，它向客户端隐藏了真实的，处理用户请求的Pod资源，使得从客户端上看，就像是由Service直接处理并响应一样，是不是很像负载均衡器呢！&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/08/29/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-14-%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0service/1349539-20190226153708890-1966593460.png"&gt;&lt;/p&gt;
&lt;p&gt;　　Service对象的IP地址也称为Cluster IP，它位于为Kubernetes集群配置指定专用的IP地址范围之内，是一种虚拟的IP地址，它在Service对象创建之后保持不变，并且能够被同一集群中的Pod资源所访问。Service端口用于接受客户端请求，并将请求转发至后端的Pod应用的相应端口，这样的代理机制，也称为端口代理，它是基于TCP/IP 协议栈的传输层。&lt;/p&gt;
&lt;h2 id="二service的实现模型"&gt;二、Service的实现模型&lt;/h2&gt;
&lt;p&gt;　　在 Kubernetes 集群中，每个 Node 运行一个 &lt;code&gt;kube-proxy&lt;/code&gt; 进程。&lt;code&gt;kube-proxy&lt;/code&gt; 负责为 &lt;code&gt;Service&lt;/code&gt; 实现了一种 VIP（虚拟 IP）的形式，而不是 &lt;code&gt;ExternalName&lt;/code&gt; 的形式。 在 Kubernetes v1.0 版本，代理完全在 userspace。在 Kubernetes v1.1 版本，新增了 iptables 代理，但并不是默认的运行模式。 从 Kubernetes v1.2 起，默认就是 iptables 代理。在Kubernetes v1.8.0-beta.0中，添加了ipvs代理。在 Kubernetes v1.0 版本，&lt;code&gt;Service&lt;/code&gt; 是 “4层”（TCP/UDP over IP）概念。 在 Kubernetes v1.1 版本，新增了 &lt;code&gt;Ingress&lt;/code&gt; API（beta 版），用来表示 “7层”（HTTP）服务。&lt;/p&gt;
&lt;p&gt;kube-proxy 这个组件始终监视着apiserver中有关service的变动信息，获取任何一个与service资源相关的变动状态，通过watch监视，一旦有service资源相关的变动和创建，kube-proxy都要转换为当前节点上的能够实现资源调度规则（例如：iptables、ipvs）&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/08/29/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-14-%E6%9C%8D%E5%8A%A1%E5%8F%91%E7%8E%B0service/1349539-20180907165901269-453271720.png"&gt;&lt;/p&gt;
&lt;h3 id="21userspace代理模式"&gt;2.1、userspace代理模式&lt;/h3&gt;
&lt;p&gt;　　这种模式，当客户端Pod请求内核空间的service iptables后，把请求转到给用户空间监听的kube-proxy 的端口，由kube-proxy来处理后，再由kube-proxy将请求转给内核空间的 service ip，再由service iptalbes根据请求转给各节点中的的service pod。&lt;/p&gt;</description></item><item><title>k8s学习笔记-12-Pod控制器--ReplicaSet、Deployment</title><link>/2018/08/28/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-12-pod%E6%8E%A7%E5%88%B6%E5%99%A8--replicasetdeployment/</link><pubDate>Tue, 28 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/28/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-12-pod%E6%8E%A7%E5%88%B6%E5%99%A8--replicasetdeployment/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一pod控制器及其功用"&gt;一、Pod控制器及其功用&lt;/h2&gt;
&lt;p&gt;Pod控制器是用于实现管理pod的中间层，确保pod资源符合预期的状态，pod的资源出现故障时，会尝试 进行重启，当根据重启策略无效，则会重新新建pod的资源。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;pod控制器有多种类型：&lt;/strong&gt;
&lt;strong&gt;ReplicaSet:&lt;/strong&gt; 代用户创建指定数量的pod副本数量，确保pod副本数量符合预期状态，并且支持滚动式自动扩容和缩容功能。
ReplicaSet主要三个组件组成：
　　（1）用户期望的pod副本数量
　　（2）标签选择器，判断哪个pod归自己管理
　　（3）当现存的pod数量不足，会根据pod资源模板进行新建
帮助用户管理无状态的pod资源，精确反应用户定义的目标数量，但是RelicaSet不是直接使用的控制器，而是使用Deployment。
**Deployment：**工作在ReplicaSet之上，用于管理无状态应用，目前来说最好的控制器。支持滚动更新和回滚功能，还提供声明式配置。
**DaemonSet：**用于确保集群中的每一个节点只运行特定的pod副本，通常用于实现系统级后台任务。比如ELK服务
特性：服务是无状态的
服务必须是守护进程
**Job：**只要完成就立即退出，不需要重启或重建。
**Cronjob：**周期性任务控制，不需要持续后台运行，
**StatefulSet：**管理有状态应用&lt;/p&gt;
&lt;h2 id="二replicaset控制器"&gt;二、ReplicaSet控制器&lt;/h2&gt;
&lt;p&gt;ReplicationController用来确保容器应用的副本数始终保持在用户定义的副本数，即如果有容器异常退出，会自动创建新的Pod来替代；而如果异常多出来的容器也会自动回收。&lt;/p&gt;
&lt;p&gt;在新版本的Kubernetes中建议使用ReplicaSet来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同，只是名字不一样，并且ReplicaSet支持集合式的selector。&lt;/p&gt;
&lt;p&gt;虽然ReplicaSet可以独立使用，但一般还是建议使用 Deployment 来自动管理ReplicaSet，这样就无需担心跟其他机制的不兼容问题（比如ReplicaSet不支持rolling-update但Deployment支持）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ReplicaSet示例：&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;（1）命令行查看ReplicaSet清单定义规则
[root@k8s-master ~]# kubectl explain rs
[root@k8s-master ~]# kubectl explain rs.spec
[root@k8s-master ~]# kubectl explain rs.spec.template
（2）新建ReplicaSet示例
[root@k8s-master ~]# vim rs-demo.yaml
apiVersion: apps/v1　　#api版本定义
kind: ReplicaSet　　#定义资源类型为ReplicaSet
metadata:　　#元数据定义
name: myapp
namespace: default
spec:　　#ReplicaSet的规格定义
replicas: 2　　#定义副本数量为2个
selector:　　　　#标签选择器，定义匹配pod的标签
matchLabels:
app: myapp
release: canary
template:　　#pod的模板定义
metadata:　　#pod的元数据定义
name: myapp-pod　　　#自定义pod的名称　
labels: 　　#定义pod的标签，需要和上面定义的标签一致，也可以多出其他标签
app: myapp
release: canary
environment: qa
spec:　　#pod的规格定义
containers:　　#容器定义
- name: myapp-container　　#容器名称
image: ikubernetes/myapp:v1　　#容器镜像
ports:　　#暴露端口
- name: http
containerPort: 80
（3）创建ReplicaSet定义的pod
[root@k8s-master ~]# kubectl create -f rs-demo.yaml
[root@k8s-master ~]# kubectl get pods　　#获取pod信息
[root@k8s-master ~]# kubectl describe pods myapp-***　　#查看pod详细信息
（4）修改pod的副本数量
[root@k8s-master ~]# kubectl edit rs myapp
replicas: 5
[root@k8s-master ~]# kubectl get rs -o wide
（5）修改pod的镜像版本
[root@k8s-master ~]# kubectl edit rs myapp
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;image: ikubernetes/myapp:v2　　
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl delete pods myapp-*** 　　#修改了pod镜像版本，pod需要重建才能达到最新版本
[root@k8s-master ~]# kubectl create -f rs-demo.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="三deployment控制器"&gt;三、Deployment控制器&lt;/h2&gt;
&lt;p&gt;Deployment为Pod和ReplicaSet（下一代Replication Controller）提供声明式更新。&lt;/p&gt;</description></item><item><title>k8s学习笔记-11-Pod状态和生命周期管理</title><link>/2018/08/27/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-11-pod%E7%8A%B6%E6%80%81%E5%92%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%AE%A1%E7%90%86/</link><pubDate>Mon, 27 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/27/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-11-pod%E7%8A%B6%E6%80%81%E5%92%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%AE%A1%E7%90%86/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一什么是pod"&gt;一、什么是Pod？&lt;/h2&gt;
&lt;p&gt;Pod是kubernetes中你可以创建和部署的最小也是最简的单位。一个Pod代表着集群中运行的一个进程。&lt;/p&gt;
&lt;p&gt;Pod中封装着应用的容器（有的情况下是好几个容器），存储、独立的网络IP，管理容器如何运行的策略选项。Pod代表着部署的一个单位：kubernetes中应用的一个实例，可能由一个或者多个容器组合在一起共享资源。&lt;/p&gt;
&lt;p&gt;在Kubrenetes集群中Pod有如下两种使用方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个Pod中运行一个容器。“每个Pod中一个容器”的模式是最常见的用法；在这种使用方式中，你可以把Pod想象成是单个容器的封装，kuberentes管理的是Pod而不是直接管理容器。&lt;/li&gt;
&lt;li&gt;在一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器，它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位——一个容器共享文件，另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pod中共享的环境包括Linux的namespace，cgroup和其他可能的隔绝环境，这一点跟Docker容器一致。在Pod的环境中，每个容器中可能还有更小的子隔离环境。&lt;/p&gt;
&lt;p&gt;Pod中的容器共享IP地址和端口号，它们之间可以通过&lt;code&gt;localhost&lt;/code&gt;互相发现。它们之间可以通过进程间通信，需要明白的是同一个Pod下的容器是通过lo网卡进行通信。例如SystemV信号或者POSIX共享内存。不同Pod之间的容器具有不同的IP地址，不能直接通过IPC通信。&lt;/p&gt;
&lt;p&gt;Pod中的容器也有访问共享volume的权限，这些volume会被定义成pod的一部分并挂载到应用容器的文件系统中。&lt;/p&gt;
&lt;p&gt;就像每个应用容器，pod被认为是临时实体。在Pod的生命周期中，pod被创建后，被分配一个唯一的ID（UID），调度到节点上，并一致维持期望的状态直到被终结（根据重启策略）或者被删除。如果node死掉了，分配到了这个node上的pod，在经过一个超时时间后会被重新调度到其他node节点上。一个给定的pod（如UID定义的）不会被“重新调度”到新的节点上，而是被一个同样的pod取代，如果期望的话甚至可以是相同的名字，但是会有一个新的UID（查看replication controller获取详情）。&lt;/p&gt;
&lt;h2 id="二pod中如何管理多个容器"&gt;二、Pod中如何管理多个容器？&lt;/h2&gt;
&lt;p&gt;Pod中可以同时运行多个进程（作为容器运行）协同工作。同一个Pod中的容器会自动的分配到同一个 node 上。同一个Pod中的容器共享资源、网络环境和依赖，它们总是被同时调度。&lt;/p&gt;
&lt;p&gt;注意在一个Pod中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。例如，你有一个容器作为web服务器运行，需要用到共享的volume，有另一个“sidecar”容器来从远端获取资源更新这些文件，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/08/27/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-11-pod%E7%8A%B6%E6%80%81%E5%92%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%AE%A1%E7%90%86/1349539-20180901112128577-178843.png"&gt;&lt;/p&gt;
&lt;p&gt;Pod中可以共享两种资源：网络和存储。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;网络&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;　　每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间，包括IP地址和端口。Pod内部的容器可以使用&lt;code&gt;localhost&lt;/code&gt;互相通信。Pod中的容器与外界通信时，必须分配共享网络资源（例如使用宿主机的端口映射）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;存储：&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;　　可以Pod指定多个共享的Volume。Pod中的所有容器都可以访问共享的volume。Volume也可以用来持久化Pod中的存储资源，以防容器重启后文件丢失。&lt;/p&gt;
&lt;h2 id="三使用pod"&gt;三、使用Pod&lt;/h2&gt;
&lt;p&gt;通常把Pod分为两类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;**自主式Pod ：**这种Pod本身是不能自我修复的，当Pod被创建后（不论是由你直接创建还是被其他Controller），都会被Kuberentes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在那个Node上。Pod不会自愈。如果Pod运行的Node故障，或者是调度器本身故障，这个Pod就会被删除。同样的，如果Pod所在Node缺少资源或者Pod处于维护状态，Pod也会被驱逐。&lt;/li&gt;
&lt;li&gt;**控制器管理的Pod：**Kubernetes使用更高级的称为Controller的抽象层，来管理Pod实例。Controller可以创建和管理多个Pod，提供副本管理、滚动升级和集群级别的自愈能力。例如，如果一个Node故障，Controller就能自动将该节点上的Pod调度到其他健康的Node上。虽然可以直接使用Pod，但是在Kubernetes中通常是使用Controller来管理Pod的。如下图：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;每个Pod都有一个特殊的被称为“根容器”的Pause 容器。 Pause容器对应的镜像属于Kubernetes平台的一部分，除了Pause容器，每个Pod还包含一个或者多个紧密相关的用户业务容器。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="img" loading="lazy" src="/2018/08/27/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-11-pod%E7%8A%B6%E6%80%81%E5%92%8C%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E7%AE%A1%E7%90%86/1349539-20180901112712875-923099036.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes设计这样的Pod概念和特殊组成结构有什么用意？？？？？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原因一：在一组容器作为一个单元的情况下，难以对整体的容器简单地进行判断及有效地进行行动。比如，一个容器死亡了，此时是算整体挂了么？那么引入与业务无关的Pause容器作为Pod的根容器，以它的状态代表着整个容器组的状态，这样就可以解决该问题。&lt;/p&gt;
&lt;p&gt;原因二：Pod里的多个业务容器共享Pause容器的IP，共享Pause容器挂载的Volume，这样简化了业务容器之间的通信问题，也解决了容器之间的文件共享问题。&lt;/p&gt;
&lt;h2 id="四pod的持久性和终止"&gt;四、Pod的持久性和终止&lt;/h2&gt;
&lt;h3 id="1pod的持久性"&gt;&lt;strong&gt;（1）Pod的持久性&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Pod在设计支持就不是作为持久化实体的。在调度失败、节点故障、缺少资源或者节点维护的状态下都会死掉会&lt;strong&gt;被驱逐&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;通常，用户不需要手动直接创建Pod，而是应该使用controller（例如&lt;a href="https://jimmysong.io/kubernetes-handbook/concepts/deployment.html"&gt;Deployments&lt;/a&gt;），即使是在创建单个Pod的情况下。Controller可以提供集群级别的自愈功能、复制和升级管理。&lt;/p&gt;
&lt;h3 id="2pod的终止"&gt;&lt;strong&gt;（2）Pod的终止&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;因为Pod作为在集群的节点上运行的进程，所以在不再需要的时候能够优雅的终止掉是十分必要的（比起使用发送KILL信号这种暴力的方式）。用户需要能够放松删除请求，并且知道它们何时会被终止，是否被正确的删除。用户想终止程序时发送删除pod的请求，在pod可以被强制删除前会有一个宽限期，会发送一个TERM请求到每个容器的主进程。一旦超时，将向主进程发送KILL信号并从API server中删除。如果kubelet或者container manager在等待进程终止的过程中重启，在重启后仍然会重试完整的宽限期。&lt;/p&gt;
&lt;p&gt;示例流程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户发送删除pod的命令，默认宽限期是30秒；&lt;/li&gt;
&lt;li&gt;在Pod超过该宽限期后API server就会更新Pod的状态为“dead”；&lt;/li&gt;
&lt;li&gt;在客户端命令行上显示的Pod状态为“terminating”；&lt;/li&gt;
&lt;li&gt;跟第三步同时，当kubelet发现pod被标记为“terminating”状态时，开始停止pod进程：
&lt;ol&gt;
&lt;li&gt;如果在pod中定义了preStop hook，在停止pod前会被调用。如果在宽限期过后，preStop hook依然在运行，第二步会再增加2秒的宽限期；&lt;/li&gt;
&lt;li&gt;向Pod中的进程发送TERM信号；&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;跟第三步同时，该Pod将从该service的端点列表中删除，不再是replication controller的一部分。关闭的慢的pod将继续处理load balancer转发的流量；&lt;/li&gt;
&lt;li&gt;过了宽限期后，将向Pod中依然运行的进程发送SIGKILL信号而杀掉进程。&lt;/li&gt;
&lt;li&gt;Kublete会在API server中完成Pod的的删除，通过将优雅周期设置为0（立即删除）。Pod在API中消失，并且在客户端也不可见。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;删除宽限期默认是30秒。&lt;strong&gt;kubectl delete&lt;/strong&gt; 命令支持 &lt;code&gt;—grace-period=&amp;lt;seconds&amp;gt;&lt;/code&gt; 选项，允许用户设置自己的宽限期。如果设置为0将强制删除pod。在kubectl&amp;gt;=1.5版本的命令中，你必须同时使用 &lt;code&gt;--force&lt;/code&gt; 和 &lt;code&gt;--grace-period=0&lt;/code&gt; 来强制删除pod。&lt;/p&gt;</description></item><item><title>k8s学习笔记-10-资源清单定义</title><link>/2018/08/25/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-10-%E8%B5%84%E6%BA%90%E6%B8%85%E5%8D%95%E5%AE%9A%E4%B9%89/</link><pubDate>Sat, 25 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/25/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-10-%E8%B5%84%E6%BA%90%E6%B8%85%E5%8D%95%E5%AE%9A%E4%B9%89/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一kubernetes常用资源"&gt;一、Kubernetes常用资源&lt;/h2&gt;
&lt;p&gt;以下列举的内容都是 kubernetes 中的 Object，这些对象都可以在 yaml 文件中作为一种 API 类型来配置。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类别&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;工作负载型资源对象&lt;/td&gt;
&lt;td&gt;Pod Replicaset ReplicationController Deployments StatefulSets Daemonset Job CronJob&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;服务发现及负载均衡&lt;/td&gt;
&lt;td&gt;Service Ingress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;配置与存储&lt;/td&gt;
&lt;td&gt;Volume、Persistent Volume、CSl 、 configmap、 secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;集群资源&lt;/td&gt;
&lt;td&gt;Namespace Node Role ClusterRole RoleBinding ClusterRoleBinding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;元数据资源&lt;/td&gt;
&lt;td&gt;HPA PodTemplate LimitRang&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="二理解kubernetes中的对象"&gt;二、理解Kubernetes中的对象&lt;/h2&gt;
&lt;p&gt;在 Kubernetes 系统中，Kubernetes 对象 是持久化的条目。Kubernetes 使用这些条目去表示整个集群的状态。特别地，它们描述了如下信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;什么容器化应用在运行（以及在哪个 Node 上）&lt;/li&gt;
&lt;li&gt;可以被应用使用的资源&lt;/li&gt;
&lt;li&gt;关于应用如何表现的策略，比如重启策略、升级策略，以及容错策略&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes 对象是 “目标性记录” —— 一旦创建对象，Kubernetes 系统将持续工作以确保对象存在。通过创建对象，可以有效地告知 Kubernetes 系统，所需要的集群工作负载看起来是什么样子的，这就是 Kubernetes 集群的 期望状态。&lt;/p&gt;
&lt;p&gt;与 Kubernetes 对象工作 —— 是否创建、修改，或者删除 —— 需要使用 Kubernetes API。当使用 &lt;code&gt;kubectl&lt;/code&gt; 命令行接口时，比如，CLI 会使用必要的 Kubernetes API 调用，也可以在程序中直接使用 Kubernetes API。&lt;/p&gt;</description></item><item><title>k8s学习笔记-09-kubernetes命令式快速创建应用</title><link>/2018/08/19/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-09-kubernetes%E5%91%BD%E4%BB%A4%E5%BC%8F%E5%BF%AB%E9%80%9F%E5%88%9B%E5%BB%BA%E5%BA%94%E7%94%A8/</link><pubDate>Sun, 19 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/19/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-09-kubernetes%E5%91%BD%E4%BB%A4%E5%BC%8F%E5%BF%AB%E9%80%9F%E5%88%9B%E5%BB%BA%E5%BA%94%E7%94%A8/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="1使用命令kubectl-run创建应用"&gt;1、使用命令kubectl run创建应用&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;语法:
kubectl run NAME --image=image [--env=&amp;#34;key=value&amp;#34;] [--port=port] [--replicas=replicas] [--dry-run=bool]
[--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;实用举例&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 #创建一个nginx的应用，副本数为1
deployment.apps/nginx-deploy created
[root@k8s-master ~]# kubectl get deployment　　#获取应用信息，查看应用是否符合预期状态
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx-deploy 1 1 1 1 40s
[root@k8s-master ~]# kubectl get pods　　#获取pod信息
NAME READY STATUS RESTARTS AGE
nginx-deploy-5b595999-44zwq 1/1 Running 0 1m
[root@k8s-master ~]# kubectl get pods -o wide #查看pod运行在哪个节点上
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deploy-5b595999-44zwq 1/1 Running 0 1m 10.244.2.2 k8s-node02
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;从上面创建的应用可以得知，nginx-deploy应用的pod的ip为10.244.2.2，这是一个pod ip，仅仅可以在集群内部访问，如下：&lt;/p&gt;</description></item><item><title>k8s学习笔记-08-Kubeadm部署集群</title><link>/2018/08/18/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-08-kubeadm%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4/</link><pubDate>Sat, 18 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/18/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-08-kubeadm%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一环境说明"&gt;一、环境说明&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;节点名称&lt;/th&gt;
&lt;th&gt;ip地址&lt;/th&gt;
&lt;th&gt;部署说明&lt;/th&gt;
&lt;th&gt;Pod 网段&lt;/th&gt;
&lt;th&gt;Service网段&lt;/th&gt;
&lt;th&gt;系统说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;k8s-master&lt;/td&gt;
&lt;td&gt;192.168.56.11&lt;/td&gt;
&lt;td&gt;docker、kubeadm、kubectl、kubelet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.244.0.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.96.0.0/12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Centos 7.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;k8s-node01&lt;/td&gt;
&lt;td&gt;192.168.56.12&lt;/td&gt;
&lt;td&gt;docker、kubeadm、kubelet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.244.0.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.96.0.0/12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Centos 7.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;k8s-node02&lt;/td&gt;
&lt;td&gt;192.168.56.13&lt;/td&gt;
&lt;td&gt;docker、kubeadm、kubelet&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.244.0.0/16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.96.0.0/12&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Centos 7.4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="1配置源"&gt;（1）配置源&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@k8s-master ~]# cd /etc/yum.repos.d/
配置阿里云的源：https://opsx.alibaba.com/mirror
[root@k8s-master yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo　　#配置dokcer源
[root@k8s-master ~]# cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/yum.repos.d/kubernetes.repo　　#配置kubernetes源
&amp;gt; [kubernetes]
&amp;gt; name=Kubernetes
&amp;gt; baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
&amp;gt; enabled=1
&amp;gt; gpgcheck=1
&amp;gt; repo_gpgcheck=1
&amp;gt; gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
&amp;gt; EOF
[root@k8s-master yum.repos.d]# yum repolist #查看可用源
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将源拷贝到node01和node02节点&lt;/p&gt;</description></item><item><title>k8s学习笔记-07-Coredns和Dashboard部署</title><link>/2018/08/17/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-07-coredns%E5%92%8Cdashboard%E9%83%A8%E7%BD%B2/</link><pubDate>Fri, 17 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/17/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-07-coredns%E5%92%8Cdashboard%E9%83%A8%E7%BD%B2/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h3 id="一coredns部署"&gt;一、CoreDNS部署&lt;/h3&gt;
&lt;p&gt;在 Cluster 中，除了可以通过 Cluster IP 访问 Service，Kubernetes 还提供了更为方便的 DNS 访问。&lt;/p&gt;
&lt;h4 id="1编辑corednsyaml文件"&gt;&lt;strong&gt;（1）编辑coredns.yaml文件&lt;/strong&gt;&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# vim coredns.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: coredns
namespace: kube-system
labels:
kubernetes.io/cluster-service: &amp;#34;true&amp;#34;
addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
kubernetes.io/bootstrapping: rbac-defaults
addonmanager.kubernetes.io/mode: Reconcile
name: system:coredns
rules:
- apiGroups:
- &amp;#34;&amp;#34;
resources:
- endpoints
- services
- pods
- namespaces
verbs:
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: &amp;#34;true&amp;#34;
labels:
kubernetes.io/bootstrapping: rbac-defaults
addonmanager.kubernetes.io/mode: EnsureExists
name: system:coredns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:coredns
subjects:
- kind: ServiceAccount
name: coredns
namespace: kube-system
---
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local. in-addr.arpa ip6.arpa {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
proxy . /etc/resolv.conf
cache 30
}
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: coredns
kubernetes.io/cluster-service: &amp;#34;true&amp;#34;
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: &amp;#34;CoreDNS&amp;#34;
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: coredns
template:
metadata:
labels:
k8s-app: coredns
spec:
serviceAccountName: coredns
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: &amp;#34;CriticalAddonsOnly&amp;#34;
operator: &amp;#34;Exists&amp;#34;
containers:
- name: coredns
image: coredns/coredns:1.0.6
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 170Mi
requests:
cpu: 100m
memory: 70Mi
args: [ &amp;#34;-conf&amp;#34;, &amp;#34;/etc/coredns/Corefile&amp;#34; ]
volumeMounts:
- name: config-volume
mountPath: /etc/coredns
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
dnsPolicy: Default
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
---
apiVersion: v1
kind: Service
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: coredns
kubernetes.io/cluster-service: &amp;#34;true&amp;#34;
addonmanager.kubernetes.io/mode: Reconcile
kubernetes.io/name: &amp;#34;CoreDNS&amp;#34;
spec:
selector:
k8s-app: coredns
clusterIP: 10.1.0.2
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="2创建coredns"&gt;&lt;strong&gt;（2）创建coredns&lt;/strong&gt;&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl create -f coredns.yaml
serviceaccount &amp;#34;coredns&amp;#34; created
clusterrole.rbac.authorization.k8s.io &amp;#34;system:coredns&amp;#34; created
clusterrolebinding.rbac.authorization.k8s.io &amp;#34;system:coredns&amp;#34; created
configmap &amp;#34;coredns&amp;#34; created
deployment.extensions &amp;#34;coredns&amp;#34; created
service &amp;#34;coredns&amp;#34; created
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="3查看coredns服务"&gt;&lt;strong&gt;（3）查看coredns服务&lt;/strong&gt;&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl get deployment -n kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
coredns 2 2 2 0 1m
[root@linux-node1 ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
coredns ClusterIP 10.1.0.2 &amp;lt;none&amp;gt; 53/UDP,53/TCP 1m
[root@linux-node1 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-77c989547b-d84n8 1/1 Running 0 2m
coredns-77c989547b-j4ms2 1/1 Running 0 2m
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="4pod容器中进行域名解析测试"&gt;&lt;strong&gt;（4）Pod容器中进行域名解析测试&lt;/strong&gt;&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl run alpine --rm -ti --image=alpine -- /bin/sh
If you don&amp;#39;t see a command prompt, try pressing enter.
/ # nslookup httpd-svc
nslookup: can&amp;#39;t resolve &amp;#39;(null)&amp;#39;: Name does not resolve
Name: httpd-svc
Address 1: 10.1.230.129
/ # wget httpd-svc:8080
Connecting to httpd-svc:8080 (10.1.230.129:8080)
index.html 100% |********************************************************************************************************************************************| 45 0:00:00 ETA
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="二dashboard部署"&gt;二、Dashboard部署&lt;/h3&gt;
&lt;p&gt;从github上下载dashboard的yaml文件：https://github.com/unixhot/salt-kubernetes&lt;/p&gt;</description></item><item><title>k8s学习笔记-06-创建K8S应用</title><link>/2018/08/16/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-06-%E5%88%9B%E5%BB%BAk8s%E5%BA%94%E7%94%A8/</link><pubDate>Thu, 16 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/16/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-06-%E5%88%9B%E5%BB%BAk8s%E5%BA%94%E7%94%A8/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h3 id="一deployment的概念"&gt;&lt;strong&gt;一、Deployment的概念&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;K8S本身并不提供网络的功能，所以需要借助第三方网络插件进行部署K8S中的网络，以打通各个节点中容器的互通。
&lt;strong&gt;POD&lt;/strong&gt;，是K8S中的一个逻辑概念，K8S管理的是POD，一个POD中包含多个容器，容器之间通过localhost互通。而POD需要ip地址。每个POD都有一个标签&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;POD–&amp;gt;RC–&amp;gt;RS–&amp;gt;Deployment （发展历程）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;，表示用户对K8S集群的一次更新操作。Deployment是一个比RS应用模式更广的API对象。用于保证Pod的副本的数量。&lt;/p&gt;
&lt;p&gt;可以是创建一个新的服务，更新一个新的服务，也可以是滚动升级一个服务。滚动升级一个服务。实际是创建一个新的RS，然后将新的RS中副本数增加到理想状态，将旧的RS中的副本数减小到0的复合操作； 这样的一个复合操作用一个RS是不太好描述的，所以用一个更通用的Deployment来描述。&lt;/p&gt;
&lt;p&gt;RC、RS和Deployment只是保证了支撑服务的POD数量，但是没有解决如何访问这些服务的问题。一个POD只是一个运行服务的实例，随时可以能在一个节点上停止，在另一个节点以一个新的IP启动一个新的POD，因此不能以确定的IP和端口号提供服务。&lt;/p&gt;
&lt;p&gt;要稳定地提供服务需要服务发现和负载均衡能力。服务发现完成的工作，是针对客户端访问的服务，找到对应的后端服务实例。&lt;/p&gt;
&lt;p&gt;在K8S的集中当中，客户端需要访问的服务就是Service对象。每个Service会对应一个集群内部有效的虚拟IP，集群内部通过虚拟IP访问一个服务。&lt;/p&gt;
&lt;h3 id="二创建k8s的第一个应用"&gt;二、创建K8S的第一个应用&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl run net-test --image=alpine --replicas=2 sleep 36000　　#创建名称为net-test的应用，镜像指定为alpine，副本数为2个
deployment.apps &amp;#34;net-test&amp;#34; created
[root@linux-node1 ~]# kubectl get pod -o wide　　#查看pod的状态信息，此时是API Server从etcd中读取这些数据
NAME READY STATUS RESTARTS AGE IP NODE
net-test-7b949fc785-2v2qz 1/1 Running 0 56s 10.2.87.2 192.168.56.120
net-test-7b949fc785-6nrhm 0/1 ContainerCreating 0 56s &amp;lt;none&amp;gt; 192.168.56.130
[root@linux-node1 ~]# kubectl get deployment net-test
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
net-test 2 2 2 2 22h
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;kubectl get deployment命令可以查看net-test的状态，输出显示两个副本正常运行。还可以在创建的过程中，通过kubectl describe deployment net-test了解详细的信息。
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl describe deployment net-test
Name: net-test
Namespace: default
CreationTimestamp: Thu, 16 Aug 2018 15:41:29 +0800
Labels: run=net-test
Annotations: deployment.kubernetes.io/revision=1
Selector: run=net-test
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: run=net-test
Containers:
net-test:
Image: alpine
Port: &amp;lt;none&amp;gt;
Host Port: &amp;lt;none&amp;gt;
Args:
sleep
360000
Environment: &amp;lt;none&amp;gt;
Mounts: &amp;lt;none&amp;gt;
Volumes: &amp;lt;none&amp;gt;
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: &amp;lt;none&amp;gt;
NewReplicaSet: net-test-5767cb94df (2/2 replicas created)
Events: &amp;lt;none&amp;gt;　　
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Events是Deployment的日志，记录整个RelicaSet的启动过程，从上面的创建过程，可以看到Deployment是通过ReplicaSet来管理Pod。&lt;/p&gt;</description></item><item><title>k8s学习笔记-05-Flannel部署</title><link>/2018/08/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-05-flannel%E9%83%A8%E7%BD%B2/</link><pubDate>Wed, 15 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/15/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-05-flannel%E9%83%A8%E7%BD%B2/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一k8s的ip地址"&gt;一、K8S的ip地址&lt;/h2&gt;
&lt;p&gt;**Node IP：**节点设备的IP，如物理机，虚拟机等容器宿主的实际IP。&lt;/p&gt;
&lt;p&gt;**Pod IP：**Pod的IP地址，是根据docker0网络IP段进行分配的。&lt;/p&gt;
&lt;p&gt;**Cluster IP：**Service的IP，是一个虚拟IP，仅作用于service对象，由K8S管理和分配，需要结合service port才能使用，单独的IP没有通信功能，集群外访问需要一些修改。&lt;/p&gt;
&lt;p&gt;在K8S集群内部，node ip、pod ip、clustere ip的通信机制是由k8s指定的路由规则，不是IP路由。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.1.0.1 &amp;lt;none&amp;gt; 443/TCP 3h
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="二flannel网络部署"&gt;二、Flannel网络部署&lt;/h2&gt;
&lt;h3 id="1为flannel生成证书"&gt;（1）为Flannel生成证书&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# vim flanneld-csr.json
{
&amp;#34;CN&amp;#34;: &amp;#34;flanneld&amp;#34;,
&amp;#34;hosts&amp;#34;: [],
&amp;#34;key&amp;#34;: {
&amp;#34;algo&amp;#34;: &amp;#34;rsa&amp;#34;,
&amp;#34;size&amp;#34;: 2048
},
&amp;#34;names&amp;#34;: [
{
&amp;#34;C&amp;#34;: &amp;#34;CN&amp;#34;,
&amp;#34;ST&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;L&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;O&amp;#34;: &amp;#34;k8s&amp;#34;,
&amp;#34;OU&amp;#34;: &amp;#34;System&amp;#34;
}
]
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2生成证书"&gt;（2）生成证书&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem \
&amp;gt; -ca-key=/opt/kubernetes/ssl/ca-key.pem \
&amp;gt; -config=/opt/kubernetes/ssl/ca-config.json \
&amp;gt; -profile=kubernetes flanneld-csr.json | cfssljson -bare flanneld
[root@linux-node1 ssl]# ll flannel*
-rw-r--r-- 1 root root 997 May 31 11:13 flanneld.csr
-rw-r--r-- 1 root root 221 May 31 11:13 flanneld-csr.json
-rw------- 1 root root 1675 May 31 11:13 flanneld-key.pem
-rw-r--r-- 1 root root 1391 May 31 11:13 flanneld.pem
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="3分发证书"&gt;（3）分发证书&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# cp flanneld*.pem /opt/kubernetes/ssl/
[root@linux-node1 ssl]# scp flanneld*.pem 192.168.56.120:/opt/kubernetes/ssl/
flanneld-key.pem 100% 1675 127.2KB/s 00:00
flanneld.pem 100% 1391 308.3KB/s 00:00
[root@linux-node1 ssl]# scp flanneld*.pem 192.168.56.130:/opt/kubernetes/ssl/
flanneld-key.pem 100% 1675 291.1KB/s 00:00
flanneld.pem 100% 1391 90.4KB/s 00:00
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="4下载flannel软件包"&gt;（4）下载Flannel软件包&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cd /usr/local/src
# wget
https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
[root@linux-node1 src]# tar zxf flannel-v0.10.0-linux-amd64.tar.gz
[root@linux-node1 src]# cp flanneld mk-docker-opts.sh /opt/kubernetes/bin/
复制到linux-node2和linux-node3节点
[root@linux-node1 src]# scp flanneld mk-docker-opts.sh 192.168.56.120:/opt/kubernetes/bin/
[root@linux-node1 src]# scp flanneld mk-docker-opts.sh 192.168.56.130:/opt/kubernetes/bin/
复制对应脚本到/opt/kubernetes/bin目录下。
[root@linux-node1 ~]# cd /usr/local/src/kubernetes/cluster/centos/node/bin/
[root@linux-node1 bin]# cp remove-docker0.sh /opt/kubernetes/bin/
[root@linux-node1 bin]# scp remove-docker0.sh 192.168.56.120:/opt/kubernetes/bin/
[root@linux-node1 bin]# scp remove-docker0.sh 192.168.56.130:/opt/kubernetes/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="5配置flannel"&gt;（5）配置Flannel&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# vim /opt/kubernetes/cfg/flannel
FLANNEL_ETCD=&amp;#34;-etcd-endpoints=https://192.168.56.110:2379,https://192.168.56.120:2379,https://192.168.56.130:2379&amp;#34;
FLANNEL_ETCD_KEY=&amp;#34;-etcd-prefix=/kubernetes/network&amp;#34;
FLANNEL_ETCD_CAFILE=&amp;#34;--etcd-cafile=/opt/kubernetes/ssl/ca.pem&amp;#34;
FLANNEL_ETCD_CERTFILE=&amp;#34;--etcd-certfile=/opt/kubernetes/ssl/flanneld.pem&amp;#34;
FLANNEL_ETCD_KEYFILE=&amp;#34;--etcd-keyfile=/opt/kubernetes/ssl/flanneld-key.pem&amp;#34;
复制配置到其它节点上
[root@linux-node1 ~]# scp /opt/kubernetes/cfg/flannel 192.168.56.120:/opt/kubernetes/cfg/
[root@linux-node1 ~]# scp /opt/kubernetes/cfg/flannel 192.168.56.130:/opt/kubernetes/cfg/
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="6设置flannel系统服务"&gt;（6）设置Flannel系统服务&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# vim /usr/lib/systemd/system/flannel.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
Before=docker.service
[Service]
EnvironmentFile=-/opt/kubernetes/cfg/flannel
ExecStartPre=/opt/kubernetes/bin/remove-docker0.sh
ExecStart=/opt/kubernetes/bin/flanneld ${FLANNEL_ETCD} ${FLANNEL_ETCD_KEY} ${FLANNEL_ETCD_CAFILE} ${FLANNEL_ETCD_CERTFILE} ${FLANNEL_ETCD_KEYFILE}
ExecStartPost=/opt/kubernetes/bin/mk-docker-opts.sh -d /run/flannel/docker
Type=notify
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
复制系统服务脚本到其它节点上
# scp /usr/lib/systemd/system/flannel.service 192.168.56.120:/usr/lib/systemd/system/
# scp /usr/lib/systemd/system/flannel.service 192.168.56.130:/usr/lib/systemd/system/
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="三flannel-cni集成"&gt;三、Flannel CNI集成&lt;/h2&gt;
&lt;h3 id="1下载cni插件"&gt;（1）下载CNI插件&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;https://github.com/containernetworking/plugins/releases
wget https://github.com/containernetworking/plugins/releases/download/v0.7.1/cni-plugins-amd64-v0.7.1.tgz
[root@linux-node1 ~]# mkdir /opt/kubernetes/bin/cni
[root@linux-node2 ~]# mkdir /opt/kubernetes/bin/cni
[root@linux-node3 ~]# mkdir /opt/kubernetes/bin/cni
[root@linux-node1 src]# tar zxf cni-plugins-amd64-v0.7.1.tgz -C /opt/kubernetes/bin/cni
[root@linux-node1 src]# scp -r /opt/kubernetes/bin/cni/* 192.168.56.120:/opt/kubernetes/bin/cni/
[root@linux-node1 src]# scp -r /opt/kubernetes/bin/cni/* 192.168.56.130:/opt/kubernetes/bin/cni/
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2创建etcd的key"&gt;（2）创建Etcd的key&lt;/h3&gt;
&lt;p&gt;此步的操作是为了创建POD的网段，并在ETCD中存储，而后FLANNEL从ETCD中取出并进行分配&lt;/p&gt;</description></item><item><title>k8s学习笔记-04-Node节点二进制部署</title><link>/2018/08/14/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-04-node%E8%8A%82%E7%82%B9%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/</link><pubDate>Tue, 14 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/14/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-04-node%E8%8A%82%E7%82%B9%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h3 id="k8s-node节点部署"&gt;K8S Node节点部署&lt;/h3&gt;
&lt;h3 id="1部署kubelet"&gt;1、部署kubelet&lt;/h3&gt;
&lt;h5 id="1二进制包准备"&gt;（1）二进制包准备&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cd /usr/local/src/kubernetes/server/bin/
[root@linux-node1 bin]# cp kubelet kube-proxy /opt/kubernetes/bin/
[root@linux-node1 bin]# scp kubelet kube-proxy 192.168.56.120:/opt/kubernetes/bin/
[root@linux-node1 bin]# scp kubelet kube-proxy 192.168.56.130:/opt/kubernetes/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="2创建角色绑定"&gt;（2）创建角色绑定&lt;/h5&gt;
&lt;p&gt;kubelet启动时会向kube-apiserver发送tsl bootstrap请求，所以需要将bootstrap的token设置成对应的角色，这样kubectl才有权限创建该请求。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
clusterrolebinding &amp;#34;kubelet-bootstrap&amp;#34; created
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="3创建-kubelet-bootstrapping-kubeconfig-文件-设置集群参数"&gt;（3）创建 kubelet bootstrapping kubeconfig 文件 设置集群参数&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cd /usr/local/src/ssl
[root@linux-node1 ssl]# kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.56.110:6443 \
--kubeconfig=bootstrap.kubeconfig
Cluster &amp;#34;kubernetes&amp;#34; set.
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="4设置客户端认证参数"&gt;（4）设置客户端认证参数&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# kubectl config set-credentials kubelet-bootstrap \
--token=ad6d5bb607a186796d8861557df0d17f \
--kubeconfig=bootstrap.kubeconfig
User &amp;#34;kubelet-bootstrap&amp;#34; set.
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="5设置上下文参数"&gt;（5）设置上下文参数&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
Context &amp;#34;default&amp;#34; created.
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="6选择默认上下文"&gt;（6）选择默认上下文&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
Switched to context &amp;#34;default&amp;#34;.
[root@linux-node1 ssl]# cp bootstrap.kubeconfig /opt/kubernetes/cfg
[root@linux-node1 ssl]# scp bootstrap.kubeconfig 192.168.56.120:/opt/kubernetes/cfg
[root@linux-node1 ssl]# scp bootstrap.kubeconfig 192.168.56.130:/opt/kubernetes/cfg
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2部署kubelete-1设置cni支持"&gt;2、部署kubelete 1.设置CNI支持&lt;/h3&gt;
&lt;h5 id="1配置cni"&gt;（1）配置CNI&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node2 ~]# mkdir -p /etc/cni/net.d
[root@linux-node2 ~]# vim /etc/cni/net.d/10-default.conf
{
&amp;#34;name&amp;#34;: &amp;#34;flannel&amp;#34;,
&amp;#34;type&amp;#34;: &amp;#34;flannel&amp;#34;,
&amp;#34;delegate&amp;#34;: {
&amp;#34;bridge&amp;#34;: &amp;#34;docker0&amp;#34;,
&amp;#34;isDefaultGateway&amp;#34;: true,
&amp;#34;mtu&amp;#34;: 1400
}
}
[root@linux-node3 ~]# mkdir -p /etc/cni/net.d
[root@linux-node2 ~]# scp /etc/cni/net.d/10-default.conf 192.168.56.130:/etc/cni/net.d/10-default.conf
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="2创建kubelet数据存储目录"&gt;（2）创建kubelet数据存储目录&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node2 ~]# mkdir /var/lib/kubelet
[root@linux-node3 ~]# mkdir /var/lib/kubelet
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="3创建kubelet服务配置"&gt;（3）创建kubelet服务配置&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node2 ~]# vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/opt/kubernetes/bin/kubelet \
--address=192.168.56.120 \
--hostname-override=192.168.56.120 \
--pod-infra-container-image=mirrorgooglecontainers/pause-amd64:3.0 \
--experimental-bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--cert-dir=/opt/kubernetes/ssl \
--network-plugin=cni \
--cni-conf-dir=/etc/cni/net.d \
--cni-bin-dir=/opt/kubernetes/bin/cni \
--cluster-dns=10.1.0.2 \
--cluster-domain=cluster.local. \
--hairpin-mode hairpin-veth \
--allow-privileged=true \
--fail-swap-on=false \
--logtostderr=true \
--v=2 \
--logtostderr=false \
--log-dir=/opt/kubernetes/log
Restart=on-failure
RestartSec=5
[root@linux-node3 ~]# vim /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/opt/kubernetes/bin/kubelet \
--address=192.168.56.130 \
--hostname-override=192.168.56.130 \
--pod-infra-container-image=mirrorgooglecontainers/pause-amd64:3.0 \
--experimental-bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \
--cert-dir=/opt/kubernetes/ssl \
--network-plugin=cni \
--cni-conf-dir=/etc/cni/net.d \
--cni-bin-dir=/opt/kubernetes/bin/cni \
--cluster-dns=10.1.0.2 \
--cluster-domain=cluster.local. \
--hairpin-mode hairpin-veth \
--allow-privileged=true \
--fail-swap-on=false \
--logtostderr=true \
--v=2 \
--logtostderr=false \
--log-dir=/opt/kubernetes/log
Restart=on-failure
RestartSec=5
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="4启动kubelet"&gt;（4）启动Kubelet&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node2 ~]# systemctl daemon-reload
[root@linux-node2 ~]# systemctl enable kubelet
[root@linux-node2 ~]# systemctl start kubelet
[root@linux-node2 kubernetes]# systemctl status kubelet
[root@linux-node3 ~]# systemctl daemon-reload
[root@linux-node3 ~]# systemctl enable kubelet
[root@linux-node3 ~]# systemctl start kubelet
[root@linux-node3 kubernetes]# systemctl status kubelet
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在查看kubelet的状态，发现有如下报错&lt;code&gt;Failed to get system container stats for &amp;quot;/system.slice/kubelet.service&amp;quot;: failed to...&lt;/code&gt;此时需要调整&lt;code&gt;kubelet&lt;/code&gt;的启动参数。&lt;/p&gt;</description></item><item><title>k8s学习笔记-03-Mater节点二进制部署</title><link>/2018/08/13/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-03-mater%E8%8A%82%E7%82%B9%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/</link><pubDate>Mon, 13 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/13/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-03-mater%E8%8A%82%E7%82%B9%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="k8s-mater节点部署"&gt;K8S Mater节点部署&lt;/h2&gt;
&lt;h3 id="1部署kubernetes-api服务部署"&gt;1、部署Kubernetes API服务部署&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;apiserver提供集群管理的REST API接口，包括认证授权、数据校验以及集群状态变更等。&lt;/li&gt;
&lt;li&gt;只有API Server才能直接操作etcd；&lt;/li&gt;
&lt;li&gt;其他模块通过API Server查询或修改数据&lt;/li&gt;
&lt;li&gt;提供其他模块之间的数据交互和通信枢纽&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="1准备软件包"&gt;（1）准备软件包&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cd /usr/local/src/kubernetes
[root@linux-node1 kubernetes]# cp server/bin/kube-apiserver /opt/kubernetes/bin/
[root@linux-node1 kubernetes]# cp server/bin/kube-controller-manager /opt/kubernetes/bin/
[root@linux-node1 kubernetes]# cp server/bin/kube-scheduler /opt/kubernetes/bin/只需要在linux-node1上拷贝
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="2创建生成csr的-json-配置文件"&gt;（2）创建生成CSR的 JSON 配置文件&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cd /usr/local/src/ssl[root@linux-node1 ssl]# vim kubernetes-csr.json
{
&amp;#34;CN&amp;#34;: &amp;#34;kubernetes&amp;#34;,
&amp;#34;hosts&amp;#34;: [
&amp;#34;127.0.0.1&amp;#34;,
&amp;#34;192.168.56.110&amp;#34;,　　#Master的ip地址
&amp;#34;10.1.0.1&amp;#34;,
&amp;#34;kubernetes&amp;#34;,
&amp;#34;kubernetes.default&amp;#34;,
&amp;#34;kubernetes.default.svc&amp;#34;,
&amp;#34;kubernetes.default.svc.cluster&amp;#34;,
&amp;#34;kubernetes.default.svc.cluster.local&amp;#34;
],
&amp;#34;key&amp;#34;: {
&amp;#34;algo&amp;#34;: &amp;#34;rsa&amp;#34;,
&amp;#34;size&amp;#34;: 2048
},
&amp;#34;names&amp;#34;: [
{
&amp;#34;C&amp;#34;: &amp;#34;CN&amp;#34;,
&amp;#34;ST&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;L&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;O&amp;#34;: &amp;#34;k8s&amp;#34;,
&amp;#34;OU&amp;#34;: &amp;#34;System&amp;#34;
}
]
}
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="3生成-kubernetes-证书和私钥"&gt;（3）生成 kubernetes 证书和私钥&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ssl]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem \
-ca-key=/opt/kubernetes/ssl/ca-key.pem \
-config=/opt/kubernetes/ssl/ca-config.json \
-profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
[root@linux-node1 ssl]# cp kubernetes*.pem /opt/kubernetes/ssl/
[root@linux-node1 ssl]# scp kubernetes*.pem 192.168.56.120:/opt/kubernetes/ssl/
[root@linux-node1 ssl]# scp kubernetes*.pem 192.168.56.130:/opt/kubernetes/ssl/
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="4-创建-kube-apiserver-使用的客户端-token-文件"&gt;（4） 创建 kube-apiserver 使用的客户端 token 文件&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# head -c 16 /dev/urandom | od -An -t x | tr -d &amp;#39; &amp;#39;
ad6d5bb607a186796d8861557df0d17f
[root@linux-node1 ~]# vim /opt/kubernetes/ssl/bootstrap-token.csv
ad6d5bb607a186796d8861557df0d17f,kubelet-bootstrap,10001,&amp;#34;system:kubelet-bootstrap&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="5-创建基础用户名密码认证配置"&gt;（5） 创建基础用户名/密码认证配置&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# vim /opt/kubernetes/ssl/basic-auth.csv
admin,admin,1
readonly,readonly,2
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="6-部署kubernetes-api-server"&gt;（6） 部署Kubernetes API Server&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# vim /usr/lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
ExecStart=/opt/kubernetes/bin/kube-apiserver \
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota,NodeRestriction \
--bind-address=192.168.56.110 \
--insecure-bind-address=127.0.0.1 \
--authorization-mode=Node,RBAC \
--runtime-config=rbac.authorization.k8s.io/v1 \
--kubelet-https=true \
--anonymous-auth=false \
--basic-auth-file=/opt/kubernetes/ssl/basic-auth.csv \
--enable-bootstrap-token-auth \
--token-auth-file=/opt/kubernetes/ssl/bootstrap-token.csv \
--service-cluster-ip-range=10.1.0.0/16 \
--service-node-port-range=20000-40000 \
--tls-cert-file=/opt/kubernetes/ssl/kubernetes.pem \
--tls-private-key-file=/opt/kubernetes/ssl/kubernetes-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--etcd-cafile=/opt/kubernetes/ssl/ca.pem \
--etcd-certfile=/opt/kubernetes/ssl/kubernetes.pem \
--etcd-keyfile=/opt/kubernetes/ssl/kubernetes-key.pem \
--etcd-servers=https://192.168.56.110:2379,https://192.168.56.120:2379,https://192.168.56.130:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/log/api-audit.log \
--event-ttl=1h \
--v=2 \
--logtostderr=false \
--log-dir=/opt/kubernetes/log
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="7-启动api-server服务"&gt;（7） 启动API Server服务&lt;/h5&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# systemctl daemon-reload
[root@linux-node1 ~]# systemctl enable kube-apiserver
[root@linux-node1 ~]# systemctl start kube-apiserver
[root@linux-node1 ~]# systemctl status kube-apiserver
[root@linux-node1 ssl]# netstat -tulnp |grep kube-apiserver
tcp 0 0 192.168.56.110:6443 0.0.0.0:* LISTEN 5052/kube-apiserver
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 5052/kube-apiserver
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;从监听端口可以看到api-server监听在6443端口，同时也监听了本地的8080端口，是提供kube-schduler和kube-controller使用。&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>k8s学习笔记-02-ETCD集群二进制部署</title><link>/2018/08/12/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-02-etcd%E9%9B%86%E7%BE%A4%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/</link><pubDate>Sun, 12 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/12/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-02-etcd%E9%9B%86%E7%BE%A4%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h3 id="etcd集群部署"&gt;ETCD集群部署&lt;/h3&gt;
&lt;p&gt;所有持久化的状态信息以KV的形式存储在ETCD中。类似zookeeper，提供分布式协调服务。之所以说kubenetes各个组件是无状态的，就是因为其中把数据都存放在ETCD中。由于ETCD支持集群，这里在三台主机上都部署上ETCD。&lt;/p&gt;
&lt;p&gt;&lt;img alt="1349539-20180706111531842-16242459" loading="lazy" src="/2018/08/12/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-02-etcd%E9%9B%86%E7%BE%A4%E4%BA%8C%E8%BF%9B%E5%88%B6%E9%83%A8%E7%BD%B2/1349539-20180706111531842-16242459.png"&gt;&lt;/p&gt;
&lt;h4 id="1准备etcd软件包"&gt;（1）准备etcd软件包&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget https://github.com/coreos/etcd/releases/download/v3.2.18/etcd-v3.2.18-linux-amd64.tar.gz
[root@linux-node1 src]# tar zxf etcd-v3.2.18-linux-amd64.tar.gz　　#解压etcd
[root@linux-node1 src]# cd etcd-v3.2.18-linux-amd64　　#有2个文件，etcdctl是操作etcd的命令
[root@linux-node1 etcd-v3.2.18-linux-amd64]# cp etcd etcdctl /opt/kubernetes/bin/
[root@linux-node1 etcd-v3.2.18-linux-amd64]# scp etcd etcdctl 192.168.56.120:/opt/kubernetes/bin/
[root@linux-node1 etcd-v3.2.18-linux-amd64]# scp etcd etcdctl 192.168.56.130:/opt/kubernetes/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="2创建-etcd-证书签名请求"&gt;（2）创建 etcd 证书签名请求&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cd /usr/local/src/ssl
[root@linux-node1 ssl]# vim etcd-csr.json
{
&amp;#34;CN&amp;#34;: &amp;#34;etcd&amp;#34;,
&amp;#34;hosts&amp;#34;: [　　#此处的ip是etcd集群中各个节点的ip地址
&amp;#34;127.0.0.1&amp;#34;,
&amp;#34;192.168.56.110&amp;#34;,
&amp;#34;192.168.56.120&amp;#34;,
&amp;#34;192.168.56.130&amp;#34;
],
&amp;#34;key&amp;#34;: {
&amp;#34;algo&amp;#34;: &amp;#34;rsa&amp;#34;,
&amp;#34;size&amp;#34;: 2048
},
&amp;#34;names&amp;#34;: [
{
&amp;#34;C&amp;#34;: &amp;#34;CN&amp;#34;,
&amp;#34;ST&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;L&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;O&amp;#34;: &amp;#34;k8s&amp;#34;,
&amp;#34;OU&amp;#34;: &amp;#34;System&amp;#34;
}
]
}
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="3生成-etcd-证书和私钥"&gt;（3）生成 etcd 证书和私钥&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cfssl gencert -ca=/opt/kubernetes/ssl/ca.pem \
-ca-key=/opt/kubernetes/ssl/ca-key.pem \
-config=/opt/kubernetes/ssl/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
会生成以下证书文件
[root@linux-node1 ~]# ls -l etcd*
-rw-r--r-- 1 root root 1045 Mar 5 11:27 etcd.csr
-rw-r--r-- 1 root root 257 Mar 5 11:25 etcd-csr.json
-rw------- 1 root root 1679 Mar 5 11:27 etcd-key.pem
-rw-r--r-- 1 root root 1419 Mar 5 11:27 etcd.pem
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="4将证书拷贝到optkubernetesssl目录下"&gt;（4）将证书拷贝到/opt/kubernetes/ssl目录下&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[root@linux-node1 ~]# cp etcd*.pem /opt/kubernetes/ssl
[root@linux-node1 ~]# scp etcd*.pem 192.168.56.120:/opt/kubernetes/ssl
[root@linux-node1 ~]# scp etcd*.pem 192.168.56.130:/opt/kubernetes/ssl
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="5配置etcd配置文件"&gt;（5）配置ETCD配置文件&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;2379端口用于外部通信，2380用于内部通信&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>k8s学习笔记-01-概念和创建证书</title><link>/2018/08/11/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-01-%E6%A6%82%E5%BF%B5%E5%92%8C%E5%88%9B%E5%BB%BA%E8%AF%81%E4%B9%A6/</link><pubDate>Sat, 11 Aug 2018 00:00:00 +0000</pubDate><guid>/2018/08/11/k8s%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-01-%E6%A6%82%E5%BF%B5%E5%92%8C%E5%88%9B%E5%BB%BA%E8%AF%81%E4%B9%A6/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="1kubernetes的重要概念"&gt;&lt;strong&gt;1、Kubernetes的重要概念&lt;/strong&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cluster&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cluster 是计算、存储和网络资源的集合，Kubernetes 利用这些资源运行各种基于容器的应用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Master&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Master 是 Cluster 的大脑，它的主要职责是调度，即决定将应用放在哪里运行。Master 运行 Linux 操作系统，可以是物理机或者虚拟机。为了实现高可用，可以运行多个 Master。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Node 的职责是运行容器应用。Node 由 Master 管理，Node 负责监控并汇报容器的状态，并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统，可以是物理机或者是虚拟机。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pod&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kubernetes 引入 Pod 主要基于下面两个目的：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;可管理性。
有些容器天生就是需要紧密联系，一起工作。Pod 提供了比容器更高层次的抽象，将它们封装到一个部署单元中。Kubernetes 以 Pod 为最小单位进行调度、扩展、共享资源、管理生命周期。&lt;/li&gt;
&lt;li&gt;通信和资源共享。
Pod 中的所有容器使用同一个网络 namespace，即相同的 IP 地址和 Port 空间。它们可以直接用 localhost 通信。同样的，这些容器可以共享存储，当 Kubernetes 挂载 volume 到 Pod，本质上是将 volume 挂载到 Pod 中的每一个容器。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Pods 有两种使用方式：&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Kubernetes之yaml文件详解</title><link>/2018/02/18/kubernetes%E4%B9%8Byaml%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/</link><pubDate>Sun, 18 Feb 2018 00:00:00 +0000</pubDate><guid>/2018/02/18/kubernetes%E4%B9%8Byaml%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h2 id="一yaml基础"&gt;一、YAML基础&lt;/h2&gt;
&lt;p&gt;YAML是专门用来写配置文件的语言，非常简洁和强大，使用比json更方便。它实质上是一种通用的数据串行化格式。&lt;/p&gt;
&lt;p&gt;YAML语法规则：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tal键，只允许使用空格
缩进的空格数目不重要，只要相同层级的元素左侧对齐即可
”#” 表示注释，从这个字符一直到行尾，都会被解析器忽略　　
在Kubernetes中，只需要知道两种结构类型即可：
Lists
Maps
123456789
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="11-yaml-maps"&gt;1.1 YAML Maps&lt;/h4&gt;
&lt;p&gt;Map顾名思义指的是字典，即一个Key:Value 的键值对信息。例如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
　　注：---为可选的分隔符 ，当需要在一个文件中定义多个结构的时候需要使用。上述内容表示有两个键apiVersion和kind，分别对应的值为v1和Pod。
123
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Maps的value既能够对应字符串也能够对应一个Maps。例如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
name: kube100-site
labels:
app: web
123456
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注：上述的YAML文件中，metadata这个KEY对应的值为一个Maps，而嵌套的labels这个KEY的值又是一个Map。实际使用中可视情况进行多层嵌套。&lt;/p&gt;
&lt;p&gt;YAML处理器根据行缩进来知道内容之间的关联。上述例子中，使用两个空格作为缩进，但空格的数据量并不重要，只是至少要求一个空格并且所有缩进保持一致的空格数 。例如，name和labels是相同缩进级别，因此YAML处理器知道他们属于同一map；它知道app是lables的值因为app的缩进更大。&lt;/p&gt;
&lt;p&gt;注意：在YAML文件中绝对不要使用tab键&lt;/p&gt;
&lt;h4 id="12-yaml-lists"&gt;1.2 YAML Lists&lt;/h4&gt;
&lt;p&gt;List即列表，说白了就是数组，例如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;args
-beijing
-shanghai
-shenzhen
-guangzhou
12345
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以指定任何数量的项在列表中，每个项的定义以破折号（-）开头，并且与父元素之间存在缩进。在JSON格式中，表示如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
&amp;#34;args&amp;#34;: [&amp;#34;beijing&amp;#34;, &amp;#34;shanghai&amp;#34;, &amp;#34;shenzhen&amp;#34;, &amp;#34;guangzhou&amp;#34;]
}
123
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当然Lists的子项也可以是Maps，Maps的子项也可以是List，例如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;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: 8080
123456789101112131415
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如上述文件所示，定义一个containers的List对象，每个子项都由name、image、ports组成，每个ports都有一个KEY为containerPort的Map组成，转成JSON格式文件：&lt;/p&gt;</description></item><item><title>k8s 常见问题</title><link>/2018/01/27/k8s-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 27 Jan 2018 00:00:00 +0000</pubDate><guid>/2018/01/27/k8s-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;自己在搭建k8s集群的时候遇到的问题,和解决方法记录下来.&lt;/p&gt;
&lt;h1 id="1etcd服务"&gt;1.etcd服务&lt;/h1&gt;
&lt;p&gt;kubernetes和flannel存储数据等，单台etcd不稳定，最好是搭建集群。搭建集群的时候，集群之间通信如果要添加认证的话，需要签署证书。同时把证书拷贝到制定文件目录，在etcd.service中制定证书文件。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat &amp;gt; etcd-csr.json &lt;span style="color:#e6db74"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;CN&amp;#34;: &amp;#34;etcd&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;hosts&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;127.0.0.1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;${NODE_IP}&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;key&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;algo&amp;#34;: &amp;#34;rsa&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;size&amp;#34;: 2048
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;names&amp;#34;: [
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;C&amp;#34;: &amp;#34;CN&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;ST&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;L&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;O&amp;#34;: &amp;#34;k8s&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;OU&amp;#34;: &amp;#34;System&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cfssl gencert -ca&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/etc/kubernetes/ssl/ca.pem &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -ca-key&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/etc/kubernetes/ssl/ca-key.pem &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -config&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/etc/kubernetes/ssl/ca-config.json &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -profile&lt;span style="color:#f92672"&gt;=&lt;/span&gt;kubernetes etcd-csr.json | cfssljson -bare etcd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p /etc/etcd/ssl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp etcd*.pem /etc/etcd/ssl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p /var/lib/etcd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat &amp;gt; etcd.service &lt;span style="color:#e6db74"&gt;&amp;lt;&amp;lt;EOF
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;[Unit]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Description=Etcd Server
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;After=network.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;After=network-online.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Wants=network-online.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Documentation=https://github.com/coreos
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;[Service]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Type=notify
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;WorkingDirectory=/var/lib/etcd/
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;ExecStart=/root/local/bin/etcd \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --name=${NODE_NAME} \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --cert-file=/etc/etcd/ssl/etcd.pem \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --key-file=/etc/etcd/ssl/etcd-key.pem \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --peer-cert-file=/etc/etcd/ssl/etcd.pem \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --peer-key-file=/etc/etcd/ssl/etcd-key.pem \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --initial-advertise-peer-urls=https://${NODE_IP}:2380 \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --listen-peer-urls=https://${NODE_IP}:2380 \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --listen-client-urls=https://${NODE_IP}:2379,http://127.0.0.1:2379 \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --advertise-client-urls=https://${NODE_IP}:2379 \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --initial-cluster-token=etcd-cluster-0 \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --initial-cluster=${ETCD_NODES} \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --initial-cluster-state=new \\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; --data-dir=/var/lib/etcd
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Restart=on-failure
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;RestartSec=5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;LimitNOFILE=65536
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;[Install]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;WantedBy=multi-user.target
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp etcd.service /etc/systemd/system/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="2flannel网络"&gt;2.flannel网络&lt;/h1&gt;
&lt;p&gt;flannel网络也可以添加认证&lt;/p&gt;</description></item><item><title>k8s学习内容汇总</title><link>/2018/01/10/k8s%E5%AD%A6%E4%B9%A0%E5%86%85%E5%AE%B9%E6%B1%87%E6%80%BB/</link><pubDate>Wed, 10 Jan 2018 00:00:00 +0000</pubDate><guid>/2018/01/10/k8s%E5%AD%A6%E4%B9%A0%E5%86%85%E5%AE%B9%E6%B1%87%E6%80%BB/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;根据马哥教育k8s教程学习。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;k8s学习大纲
- 基础大纲
- 集群部署及陈述式命令管理
- 资源类型及配置清单
- pod资源
- pod 控制器
- service资源
- 存储卷
- configmap与secret资源
- statefulset控制器
- 认证、授权及准入控制
- 网络模型及网络策略
- pod资源调度
- crd、自定义资源、自定义控制器及自定义API server, cni=Custom/Container Network Interface, crd=CustomResourceDefinition, CRI=Container Runtime Interface
- 资源指标与HPA控制器
- Helm管理器
- 高可用kubernetes
Cloud Native Apps: 云原生应用，程序开发出来就是运行在云平台上，而非单机上的应用。
Serverless: 与云原生应用组合，成为新的发展趋势，FaaS。 Knative。
单体应用程序: 亦称巨石应用，牵一发而动全身。
分成架构服务: 每个团队维护一个层次。（比如用户，商品，支付）
微服务(Microservice): 服务拆分成多个小功能，单独运行。
- 服务注册和服务发现: 分布式和微服务存在的问题
- 三五个程序运行支撑的服务转变为 三五十个微型服务，服务之间的调用成为网状结构。
- 非静态配置，动态服务发现，服务总线
- 服务编排系统: 解决运维部署难的问题
- 容器编排系统: 解决系统异构，服务依赖环境各不相同。 服务编排系统 --&amp;gt; 容器编排系统
容器编排系统: (主流: k8s, Borg, Docker Swarm, Apache Mesos Marathon DC/OS )
what is container orchestration?
- container orchestration is all about managing the lifecycles of containers, especially in large, dynamic environments.
- software teams use container orchestration to control and automade many task:
- provisioning and deployment of containers
- redundancy and availability of containers
- scaling up or removing containers to spread application load evently across host infrastructure
- movement of containers from one host to another if there is a shortage of resources in host, or if a host dies.
- allocation of resources between containers
- exteral exposure of services running in a container with the outside world
- load balancing of service discovery between containers
- heath monitoring of containers and hosts
- configuration of an application in relation to the containers runing it
简单来说，容器编排是指容器应用的自动布局、协同及管理，它主要负责完成以下具体内容：
service discovery
load balancing
secrets/configuration/storage management
heath checks
auto-[scaling/restart/healing] of containers and nodes
zero-downtime deploys
- pod资源
- pod 控制器:
pod创建方式:
- 自助式pod: 直接创建pod
- 由控制器管理pod: 创建deployment,service等
ReplicationControler:
ReplicaSet/rs:
- 副本数
- 标签选择
- pod资源摸版
- kubectl explain rs
- kubectl explain rs.spec
- replicas
- selector
- template
Deployment: 无状态任务,关注群体行为. 只关注数量,不关注个体.
- kubectl explain deploy.spec
- replicas
- selector
- template
- strategy: 更新策略
- rollingUpdate
- maxSurge: 最多超出目标pod数量 1/20%
- maxUnavailable: 最多不可用数量. 1/80%
- type
- Recreate
- rollingUpdate
- minReadySeconds
- revisionHistoryLimit: 保存历史版本数量限制
DaemonSet/ds: 每个node节点只运行一个,eg:ELK.
- kubectl explain ds.spec
- selector
- template
- minReadySeconds
- revisionHistoryLimit: 保存历史版本数量限制
- updateStrategy
Service:
工作模式: userspace, iptables, ipvs. (kube-proxy)
userspace: 1.1-
iptables: 1.10-
ipvs: 1.11+
- NodePort/ClusterIP : client --&amp;gt; NodeIP:NodePort --&amp;gt; ClusterIP:ServicePort --&amp;gt; PodIP:containerPort
- LBAAS(LoadBalancerAsAService): 公有云环境中.
- LoadBalancer
- ExternalName
- FQDN
- CNAME -&amp;gt; FQDN
- No ClusterIP: Headless Service
- ServiceName -&amp;gt; PodIP
- kubectl explain svc
- type: ExternalName, ClusterIP, NodePort, LoadBalancer
- port:
- NodePort # type=NodePort 时 可用. client --&amp;gt; NodeIP:NodePort --&amp;gt; ClusterIP:ServicePort --&amp;gt; PodIP:containerPort
- LBAAS(LoadBalancerAsAService): 公有云环境中.
- LoadBalancer
- ExternalName
- FQDN
- CNAME -&amp;gt; FQDN
-
- port
- targetPort
Ingress:
Service: ingress-nginx (NodePort, DaemonSet - HostNetwork)
IngressController: ingress-nginx
Ingress:
- site1.ikubernetes.io (virtual host)
- site2.ikubernetes.io (virtual host)
- example.com/path1
- example.com/path2
- Service: site1
- pod1
- pod2
- Service: site2
- pod3
- pod4
- 存储卷
- emptyDir
- 临时目录, 内存使用, 没有持久性
- gitRepo
- hostPath
- 共享存储
- SAN: iSCSI
- NAS: nfs, cifs, http
- 分布式存储:
- glusterfs
- ceph: rbd
- cephfs:
- 云存储
- EBS
- Azure Disk
- pvc: persistentVolumeClaim
- pv
- pvc
- pod - volumes -
- secret
base64 的 configmap
- configmap: 配置中心
配置容器化应用的方式:
1. 自定义命令行参数;
args: []
2.把配置文件直接copy进镜像
3.环境变量
1.Cloud Native的应用程序一般可直接通过环境变量加载配置
2.通过entrypoint.sh脚本来预处理变量为配置文件中的配置信息
4.存储卷
- 变量注入 --&amp;gt; pod 读取变量
- 挂载存储卷 --&amp;gt; pod 读取配置
- 自定义命令行参数
- StatefulSet:
PetSet -&amp;gt; StatefulSet
应对有以下要求的服务:
1.稳定且唯一的网络标识符
2.稳定且持久的存储
3.有序平滑的部署和扩展
4.有序平滑的删除和终止
5.有序的滚动更新
三个组件:
- headless service: clusterIP: None
- StatefulSet
- volumeClaimTemplate
- 认证、授权及准入控制
- Authentication
- restful API: token
- tls: 双向认证
- user/password
- Authorization
- rbac
- role
- rolebinding
- ClusterRole
- ClusterRoleBinding
- webhook
- abac
- Admission Control
client --&amp;gt; API Server
pod --&amp;gt; api server
- ServiceAccount?
- secret
- ServiceAccountName
kubectl get secret
kubectl get sa | serviceaccount
kubectl create serviceaccount my-sa -o yaml --dry-run
kubectl get pods myapp -o yaml --export
API request path: http://IP:port/apis/apps/v1/namespaces/default/deployments/myapp-deploy/
http request ver:
get, post, put, delete
http request --&amp;gt; API requests verb:
get, list, create, update, patch, watch, proxy, redirect, delete, delectcollection
Resource:
Subresource:
Namespace:
API group:
- ServiceAccount:
alex.crt
(umask 077; openssl genrsa -out alex.key 2048)
openssl req -new -key alex.key -out alex.csr -subj &amp;#34;/CN=alex&amp;#34;
openssl x509 -req -in alex.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out alex.crt -days 3650
openssl x509 -in alex.crt -text -noout
kubectl config set-cluster alex-cluster --server=&amp;#34;https://192.168.137.131:6443&amp;#34; --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --kubeconfig=/tmp/alex.conf
kubectl config set-credentials admin \
--client-certificate=datasets/work/admin/admin.pem \
--client-key=datasets/work/admin/admin-key.pem \
--embed-certs=true \
--kubeconfig=/tmp/alex.conf
kubectl config set-context alex@kubernetes --cluster=kubernetes --user=admin --kubeconfig=/tmp/alex.conf
kubectl config use-context kubernetes --kubeconfig=/tmp/alex.conf
kubectl get pods --kubeconfig=/tmp/alex.conf (error from server forbidden)
- RBAC
- role, clusterrole
object:
resource group
resource
non-resource url
action:
get, list, watch, patch, delete, deletecollection, ...
- rolebinding, clusterrolebinding
subject:
user
group
serviceaccount
role:
- role:
- operations
- objects
- rolebinding:
- user account or service account
- role
- clusterrole
- clusterrolebinding
# kubectl create role --help
# kubectl create rolebinding --help
# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: pods-reader
namespace: default
rules:
- apiGroups:
- &amp;#34;&amp;#34;
resources:
- pods
verbs:
- get
- list
- watch
# kubectl create rolebinding alex-read-pods --role=pods-reader --user=alex --dry-run=client -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: alex-read-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: alex
# 接着上面 ServiceAccount 的例子
# kubectl config use-context kubernetes --kubeconfig=/tmp/alex.conf
# kubectl get pods --kubeconfig=/tmp/alex.conf
# kubectl get pods -n kube-system --kubeconfig=/tmp/alex.conf (error from server forbidden)
# kubectl create clusterrole --help
# kubectl create clusterrolebinding --help
- Kubernetes Dashboard
- helm install kubernetes-dashboard/kubernetes-dashboard --version 2.3.0 --name=k8s-dashboard [--namespaces=dashboard]
- helm fetch kubernetes-dashboard/kubernetes-dashboard --version 2.3.0
- tar xf kubernetes-dashboard-2.3.0.tgz
- vim kubernetes-dashboard/values.yaml
- helm install kubernetes-dashboard/kubernetes-dashboard --version 2.3.0 --name=k8s-dashboard -f kubernetes-dashboard/values.yaml [--namespaces=dashboard]
- kubectl create clusterrolebinding k8s-dashboard-admin --clusterrole=cluster-admin --serviceaccount=default:k8s-dashboard / [--serviceaccount=dashboard:k8s-dashboard]
- kubectl describe sa k8s-dashboard [-n dashboard]
- kubectl describe secret k8s-dashboard-token-xxxx [-n dashboard]
- 网络模型及网络策略
flannel
kubectl get daemonset -n kube-system
kubectl get pods -o wide -n kube-system |grep -i kube-flannel
kubectl get configmap -n kube-system
kubectl get configmap kube-flannel-cfg -o json -n kube-system
from 10.244.1.59 ping 10.244.2.76
tcpdump -i cni0 -nn icmp
tcpdump -i flannel.1 -nn
tcpdump -i ens32 -nn host 192.168.137.131
overlay otv
calico
- pod资源调度
调度器:
预选策略:
优先函数:
节点选择器: nodeSelector, nodeName
节点亲和调度: nodeAffinity
taint的effect定义对Pod排斥效果:
NoSchedule:仅影响调度过程,对现存的Pod对象不产生影响;
NoExecute:既影响调度过程,也影响现在的Pod对象;不容忍的Pod对象将被驱逐;
PreferNoSchedule:
- crd、自定义资源、自定义控制器及自定义API server
- HeapSter (数据采集)
- cAdvisor (数据指标检测)
- InfluxDB (历史数据记录: 时序数据库系统)
- Grafana (数据展示)
- RBAC
资源指标:
metrics-server: k8s资源聚合器
自定义指标:
- prometheus
- k8s-prometheus-adapter
- MertricServer
- PrometheusOperator
- NodeExporter
- kubeStateMetrics
- Prometheus
- Grafana
新一代架构:
核心指标流水线:
由kubelet、metrics-server以及由API server提供的api组成;CPU累积使用率、内存实时使用率、Pod的资源占用率及容器的磁盘占用率;
监控流水线:
用于从系统收集各种指标数据并提供终端用户、存储系统以及HPA,它们包含核心指标及许多非核心指标。非核心指标本身不能被k8s所解析,
metrics-server:
API server
- Helm管理器: chart repository
Tiller:
chart:
- 配置清单
- 模板文件
-
helm install mem1 stable/memcached
# kubectl explain ingress.spec
FIELDS:
backend &amp;lt;Object&amp;gt;
resource &amp;lt;Object&amp;gt;
serviceName &amp;lt;string&amp;gt;
servicePort &amp;lt;string&amp;gt;
ingressClassName &amp;lt;string&amp;gt;
rules &amp;lt;[]Object&amp;gt;
host &amp;lt;string&amp;gt;
http &amp;lt;Object&amp;gt;
paths &amp;lt;[]Object&amp;gt; -required-
backend &amp;lt;Object&amp;gt; -required-
path &amp;lt;string&amp;gt;
pathType &amp;lt;string&amp;gt;
tls &amp;lt;[]Object&amp;gt;
Ingress Controller:
- Nginx
- Traefik
- Envoy
namespace: ingress-nginx
Job: 一次性任务
Cronjob: 周期性任务
StatefulSet: 关注个体. 对
EDR: Custom Defined Resources, 1.8+
Operator: etcd
example:
- # ReplicaSet
- vim rs-demo.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
name: myapp-pod
labels:
app: myapp
release: canary
environments: qa
sepe:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
- kubectl create -f rs-demo.yaml
- kubectl edit rs myapp --&amp;gt; replicas: 5
- kubectl get pods
- kubectl edit rs myapp --&amp;gt; image: ikubernetes/myapp:v2
- kubectl get rs -o wide
- curl xx.xx.xxx.xx # 只有重建的pod会使用新的image
- # Deployment
- vim deploy-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
name: myapp-pod
labels:
app: myapp
release: canary
environments: qa
sepe:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
- kubectl apply -f deploy-demo.yaml
- kubectl get deploy
- kubectl get rs -o wide
myapp-deploy-69b47bc96d --&amp;gt; 模板的hash值
- kubectl get pods
- kubectl get pods -l app=myapp -w # 新开窗口
- vim deploy-demo.yaml --&amp;gt; image: ikubernetes/myapp:v2
- kubectl apply -f deploy-demo.yaml
- kubectl get rs -o wide
- kubectl rollout history deployment myapp-deploy
# 打补丁方式增加pod
- kubectl patch deployment myapp-deploy -p &amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;replicas&amp;#34;:5}}&amp;#39;
- kubectl get pods
- kubectl patch deployment myapp-deploy -p &amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;strategy&amp;#34;:{&amp;#34;rollingUpdate&amp;#34;:{&amp;#34;maxSurge&amp;#34;:1,&amp;#34;maxUnavailable&amp;#34;:0}}}}&amp;#39;
- kubectl describe deployment myapp-deploy
- kubectl get pods -l app=myapp -w # 新开窗口-1
- kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v3 &amp;amp;&amp;amp; kubectl rollout pause deployment myapp-deploy # 暂停rollout, 金丝雀发布
- kubectl rollout status deployment myapp-deploy # 新开窗口-2
- kubectl rollout resume deployment myapp-deploy --&amp;gt; # 查看新开窗口 1, 2
- kubectl rollout history deployment myapp-deploy # 查看历史版本
- kubectl get rs -o wide
# 回滚版本
- kubectl rollout undo --help
- kubectl rollout undo deployment myapp-deploy --to-revision=1
- kubectl rollout history deployment myapp-deploy # 查看历史版本
- # DaemonSet
- vim ds-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespaces: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: logstor
template:
metadata:
labels:
app: redis
role: logstor
spec:
containers:
- name: redis
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: filebeat
release: stable
template:
metadata:
name: filebeat-pod
labels:
app: filebeat
release: stable
sepe:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alphine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: REDIS_LOG_LEVEL
value: info
- kubectl apply -f ds-demo.yaml
- kubectl get pods
- kubectl expose deployment redis --port=6379
- kubect get svc
- kubectl exec -it redist-5bxxxx-xxx -- /bin/sh
# netstat -tnl
# nslookup redis.default.svc.cluster.local
# redis-cli -h redis.default.svc.cluster.local
# kyes *
# DaemonSet 滚动更新
- kubectl set image demonsets filebeat-ds filebeat=ikubernets/filebeat-5.6.6-alphine
- kubectl get pods -w # 一个一个的更新.
- # Service
- vim redis-svc.yaml
apiVersion: v1
kind: Service
medatada:
name: redis
namespace: default
spec:
selector:
app: redis
role: logstor
# clusterIP: 10.96.96.96
type: ClusterIP
port:
- port: 6349
targetPort: 6379
- kubectl apply -f redis-svc.yaml
- kubectl get svc
- kubectl describe svc redis
-
- curl xx.xx.xxx.xx # 只有重建的pod会使用新的image
- service资源
Helm: like Linux yum/apt/apk ...
k8s Server
Master
API Server
- port: 6443
- auth: 双向认证, /etc/kubernetes/pki
- config: ~/.kube/config
- kubectl config view
- restful api
- kubectl api-versions
- json
- kubectl get pod == curl https://master:6443/v1/...
- communicate with all the service
- kubectl
- kube-controller-manager
- kube-scheduler
- etcd
- kubelet
- kube-proxy
- api 接口中的资源分成多个逻辑组合 apiVersion
- 和解循环（Reconciliation Loop）: status --&amp;gt; spec
Scheduler
Controller
- 和解循环（Reconciliation Loop）: status --&amp;gt; spec
Node:
- pod
- service -&amp;gt; iptables/ipvs -&amp;gt; kube-proxy
- kube-proxy
Resource
资源有两个级别：
- 集群级别
- Node
- Namespace
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
- PersistentVolume
- 名称空间级别
- pod
- service
- deploy
- 元数据型资源
- HPA
- PodTemplate
- LimitRange
资源组成部分：
- apiVersion: group/version (kubectl api-versions)
- kind: 资源类别
- metadata
- spec: 资源期望状态
- labels/tag: kubectl label
- annotations: kubectl annotate
- initContainers: kubectl explain pods.spec.initContainers: 容器初始化, 运行前, 运行后, 运行时 (存活检测, 就绪检测)
- lifecycle
- livenessProbe
- readinessProbe
- startupProbe
-
- Containers: kubectl explain pods.spec.Containers: 容器初始化, 运行前, 运行后, 运行时 (存活检测, 就绪检测)
- lifecycle: preStart hook, preStop hook
- livenessProbe
- readinessProbe
- startupProbe
- name:
- command: [&amp;#34;/bin/bash&amp;#34; &amp;#34;-c&amp;#34; &amp;#34;sleep 3600&amp;#34;]
- args:
- image:
- imagePullPolicy:
- Never
- Always
- IfNotPresent
- port:
- name:
- hostIP:
- hostPort:
- protocol
- containerPort
- status: 资源当前状态
资源引用Object URL:
/apis/&amp;lt;GROUP&amp;gt;/&amp;lt;VERSION&amp;gt;/namespaces/&amp;lt;NAMESPACE_NAME&amp;gt;/&amp;lt;KIND&amp;gt;[/OBJECT_ID]/
- /api/GROUP/VERSION/namespaces/NAMESPACE/TYPE/NAME
- kubectl get pod/nginx-ds-s4hpn
- selfLink: /api/v1/namespaces/default/pods/nginx-ds-s4hpn
资源记录:
SVC_NAME.NS_NAME.DOMAIN.LTD.
redis.default.svc.cluster.local
- Pod
- Pod Controller
- Deployment: 类型 --&amp;gt; ngx-deploy --&amp;gt; nginx pod
- Service
- nginx-svc --&amp;gt; 关联到 nginx pod
kubeadm
kubectl
- kubectl explain pods.spec.initContainers
- kubectl -h
- basic commands beginner
- create
- expose
- run
- set
- basic commands intermediate
- explan
- get
- edit
- delete
- deploy commands
- rollout
- scale
- autoscale
- cluster management commands
- certificate
- cluster-info
- top
- cordon
- uncordon
- drain
- taint
- troubleshooting and debugging commands
- describe
- logs
- attach
- exec: kubectl exec -it PodName -c ContainerName -- /bin/sh
- port-forward
- kubectl config view [-o wide/json/yaml]
# kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.137.131:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- kubectl api-resources: 支持的资源类型 以及缩写
- kubectl get [-o wide/json/yaml] [-n default/kube-system/...] [-L label-name] [-l label-name ==/!= label-value]
- all
- nodes
- pods
- ns/namespace
- default
- kube-public
- kube-system
- deploy
- svc/service
- kubectl create [ -f file]
- job
- namespace
- kubectl create namespace testing
- kubectl create namespace prod
- kubectl create namespace develop
- kubectl get ns
- kubectl delete namespace testing
- kubectl delete ns/prod ns/develop
- deployment
- kubectl create deployment nginx-deploy --image=nginx:1.14-alpine
- kubectl get all -o wide
- pod/nginx-deploy-xxxx (ip: 10.244.1.2)
- deployment.apps/nginx-deploy
- replicaset.apps/nginx-deploy-xxxx
- curl 10.244.1.2 ( welcome nginx!)
- kubectl delete pod/nginx-deploy-xxxx
- kubectl get all -o wide
- pod/nginx-deploy-xxxx (ip: 10.244.3.2)
...
- curl 10.244.3.2 ( welcome nginx!)
- service
- kubectl create service -h
- ClusterIP
- NodePort
- kubectl create service clusterip nginx-deploy --tcp=80:80 (名字和上面deploy保持一致，就会自动分配IP)
- kubectl get svc/nginx-deploy -o yaml
- clusterip： 10.110.129.64
- endpoints: 10.244.3.2
- kubectl describe svc/nginx-deploy
# 删除 pod 测试
- curl 10.110.129.64 ( welcome nginx!)
- kubectl delete pod/nginx-deploy-xxxx
- kubectl get all -o wide
- pod/nginx-deploy-xxxx (ip: 10.244.1.3)
...
- kubectl get svc/nginx-deploy -o yaml
- clusterip： 10.110.129.64
- endpoints: 10.244.1.3 (自动关联到最新的pod)
# 删除 service 测试
- curl nginx-deploy.default.svc.cluster.local. ( welcome nginx!)
- kubectl delete svc/nginx-deploy
- kubectl create service clusterip nginx-deploy --tcp=80:80 (名字和上面deploy保持一致，就会自动分配IP)
- kubectl describe svc/nginx-deploy -o yaml
- clusterip： 10.111.215.249
- endpoints: 10.244.3.2
- curl nginx-deploy.default.svc.cluster.local. ( welcome nginx!)
# 按需伸缩 pod 测试
- kubectl create deploy myapp --image=ikubernetes/myapp:v1
- kubectl get deploy
- kubectl get pods -o wide
- ip : 10.244.3.3
- curl 10.244.3.3
- curl 10.244.3.3/hostname.html (show the pod name: myapp-xxxx-yyyy)
- kubectl create service clusterip myapp --tcp=80:80
- kubectl describe svc/myapp
- IP 10.100.182.218
- Endpoints: 10.244.3.3
- curl nginx-deploy.default.svc.cluster.local. ( welcome myapp!)
- curl nginx-deploy.default.svc.cluster.local/hostname.html (show the pod name: myapp-xxxx-yyyy)
- kubectl scale --replicas=3 myapp (deploy name)
- kubectl describe svc/myapp
- IP 10.100.182.218
- Endpoints: 10.244.3.3, 10.244.1.4, 10.244.2.2
- curl nginx-deploy.default.svc.cluster.local/hostname.html (随机显示不同IP的pod name，多次重复执行查看效果)
- kubectl scale --replicas=2 myapp
- kubectl describe svc/myapp
- IP 10.100.182.218
- Endpoints: 10.244.3.3, 10.244.1.4
# nodeport 外网访问
- kubectl delete svc/myapp
- kubectl create service nodeport -h
- kubectl create service nodeport myapp --tcp=80:80
- kubectl get svc
- ports: 80:31996/TCP
- 集群外部访问所有nodes的 http://nodesip:31996/hostname.html
- 自动创建规则在每一个节点的iptables --&amp;gt; kube-proxy
- ssh nodes &amp;#34;iptables -t nat -vnL&amp;#34;
eg:
- kubectl expose
- kubectl set image deployment myapp myapp=ikubernetes/myapp:v2
- kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
kubectl label pods -n dev-namespaces apptag=my-app release=stable deltag-
- kubectl api-versions
- kubectl describe
Network
- node network
- service network: service 注册/发现
- pod network
外网访问:
- Service: NodePort
- hostport:
- hostNetwork:
ipvs/iptables 4 层调度器 ingress 7 层调度器
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>k8s 安装</title><link>/2017/12/24/k8s-%E5%AE%89%E8%A3%85/</link><pubDate>Sun, 24 Dec 2017 00:00:00 +0000</pubDate><guid>/2017/12/24/k8s-%E5%AE%89%E8%A3%85/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="一在master节点上的操作"&gt;一、在master节点上的操作&lt;/h1&gt;
&lt;p&gt;众多需要下载和安装的包我都已经下载好了放在集群上，所以后面的安装等就是直接从集群backup目录拷贝过来直接用。&lt;/p&gt;
&lt;p&gt;master节点配置的服务有，etcd，flannel，docker，kubectl，kube-apiserver，kube-controller-manager，kube-scheduler，kubelete，kube-proxy，kubedns（插件），kube-dashboard（插件）&lt;/p&gt;
&lt;h2 id="1首先设置环境变量"&gt;1.首先设置环境变量&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat /atlas/backup/kubernetes-1.7.6/environment.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/bash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BOOTSTRAP_TOKEN&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;41f7e4ba8b7be874fcff18bf5cf41a7c&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SERVICE_CIDR&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;10.254.0.0/16&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CLUSTER_CIDR&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;172.30.0.0/16&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NODE_PORT_RANGE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;8400-9000&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export ETCD_ENDPOINTS&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;http://172.16.10.18:2379,http://172.16.10.10:2379&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export FLANNEL_ETCD_PREFIX&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/flannel/network&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export CLUSTER_KUBERNETES_SVC_IP&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;10.254.0.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export CLUSTER_DNS_SVC_IP&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;10.254.0.2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export CLUSTER_DNS_DOMAIN&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;cluster.local.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2下载cfssl"&gt;2.下载cfssl&lt;/h2&gt;
&lt;p&gt;后面使用cfssl来生成certificate authority&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /atlas/backup/kubernetes-1.7.6/cfssl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp cfssl_linux-amd64 /usr/local/bin/cfssl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp cfssljson_linux-amd64 /usr/local/bin/cfssljson
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3创建ca配置文件ca-configjson和签名请求ca-csrjson"&gt;3.创建CA配置文件ca-config.json和签名请求ca-csr.json&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir /atlas/backup/kubernetes-1.7.6/ssl
cd /atlas/backup/kubernetes-1.7.6/ssl/
# vim /atlas/backup/kubernetes-1.7.6/ssl/ca-config.json
cat &amp;gt; ca-config.json &amp;lt;&amp;lt;EOF
{
&amp;#34;signing&amp;#34;: {
&amp;#34;default&amp;#34;: {
&amp;#34;expiry&amp;#34;: &amp;#34;8760h&amp;#34;
},
&amp;#34;profiles&amp;#34;: {
&amp;#34;kubernetes&amp;#34;: {
&amp;#34;usages&amp;#34;: [
&amp;#34;signing&amp;#34;,
&amp;#34;key encipherment&amp;#34;,
&amp;#34;server auth&amp;#34;,
&amp;#34;client auth&amp;#34;
],
&amp;#34;expiry&amp;#34;: &amp;#34;8760h&amp;#34;
}
}
}
}
EOF
# vim /atlas/backup/kubernetes-1.7.6/ssl/ca-csr.json
cat &amp;gt; ca-csr.json &amp;lt;&amp;lt;EOF
{
&amp;#34;CN&amp;#34;: &amp;#34;kubernetes&amp;#34;,
&amp;#34;key&amp;#34;: {
&amp;#34;algo&amp;#34;: &amp;#34;rsa&amp;#34;,
&amp;#34;size&amp;#34;: 2048
},
&amp;#34;names&amp;#34;: [
{
&amp;#34;C&amp;#34;: &amp;#34;CN&amp;#34;,
&amp;#34;ST&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;L&amp;#34;: &amp;#34;BeiJing&amp;#34;,
&amp;#34;O&amp;#34;: &amp;#34;k8s&amp;#34;,
&amp;#34;OU&amp;#34;: &amp;#34;System&amp;#34;
}
]
}
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="4生成证书和私钥"&gt;4.生成证书和私钥&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cfssl gencert -initca ca-csr.json | cfssljson -bare ca
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls ca*
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -pv /etc/kubernetes/ssl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cp /atlas/backup/kubernetes-1.7.6/ssl/ca* /etc/kubernetes/ssl
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="5加载环境变量"&gt;5.加载环境变量&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NODE_NAME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;etcd-host0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NODE_IP&lt;span style="color:#f92672"&gt;=&lt;/span&gt;172.16.10.10
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export NODE_IPS&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;172.16.10.10 172.16.10.18&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export ETCD_NODES&lt;span style="color:#f92672"&gt;=&lt;/span&gt;etcd-host0&lt;span style="color:#f92672"&gt;=&lt;/span&gt;http://172.16.10.10:2380,etcd-host1&lt;span style="color:#f92672"&gt;=&lt;/span&gt;http://172.16.10.18:2380
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source /atlas/backup/kubernetes-1.7.6/environment.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="6配置etcd服务"&gt;6.配置etcd服务&lt;/h2&gt;
&lt;p&gt;kuberntes 系统使用 etcd 存储所有数据，同时flannel网络服务也会把数据保存到etcd中，etcd服务集群只在login节点和master节点搭建。有些教程在etcd集群和flannel集群中加入了ca认证过程，这里为了简单就没有加密。&lt;/p&gt;</description></item><item><title>01-Kubernetes 基础概念和架构解析</title><link>/2017/12/17/01-kubernetes-%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5%E5%92%8C%E6%9E%B6%E6%9E%84%E8%A7%A3%E6%9E%90/</link><pubDate>Sun, 17 Dec 2017 00:00:00 +0000</pubDate><guid>/2017/12/17/01-kubernetes-%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5%E5%92%8C%E6%9E%B6%E6%9E%84%E8%A7%A3%E6%9E%90/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="1服务部署的发展"&gt;1.服务部署的发展&lt;/h1&gt;
&lt;p&gt;为什么我们需要Kubernetes? 我们先来看看服务部署的发展. 如下图:&lt;/p&gt;
&lt;p&gt;&lt;img alt="container_evolution" loading="lazy" src="/2017/12/17/01-kubernetes-%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5%E5%92%8C%E6%9E%B6%E6%9E%84%E8%A7%A3%E6%9E%90/container_evolution.svg"&gt;&lt;/p&gt;
&lt;h2 id="11-传统部署时代"&gt;1.1 &lt;strong&gt;传统部署时代&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;早期，组织在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界，这会导致资源分配问题。例如，如果在物理服务器上运行多个应用程序，则可能会出现一个应用程序占用大部分资源的情况，结果可能导致其他应用程序的性能下降。一种解决方案是在不同的物理服务器上运行每个应用程序，但是由于资源利用不足而无法扩展，并且组织维护许多物理服务器的成本很高。&lt;/p&gt;
&lt;h2 id="12-虚拟化部署时代"&gt;1.2 &lt;strong&gt;虚拟化部署时代&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;作为解决方案，引入了虚拟化功能，它允许您在单个物理服务器的 CPU 上运行多个虚拟机（VM）。于是有了xen, kvm, vmware 和 virualbox 等虚拟化应用的出现.&lt;/p&gt;
&lt;p&gt;虚拟化功能允许应用程序在 VM 之间隔离，并提供安全级别，因为一个应用程序的信息不能被另一应用程序自由地访问。&lt;/p&gt;
&lt;p&gt;因为虚拟化可以轻松地添加或更新应用程序、降低硬件成本等等，所以虚拟化可以更好地利用物理服务器中的资源，并可以实现更好的可伸缩性。&lt;/p&gt;
&lt;p&gt;每个 VM 是一台完整的计算机，在虚拟化硬件之上运行所有组件，包括其自己的操作系统。&lt;/p&gt;
&lt;h2 id="13-容器部署时代"&gt;1.3 &lt;strong&gt;容器部署时代&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;容器类似于 VM，但是它们具有轻量级的隔离属性，可以在应用程序之间共享操作系统（OS）。因此，容器被认为是轻量级的。容器与 VM 类似，具有自己的文件系统、CPU、内存、进程空间等。由于它们与基础架构分离，因此可以跨云和 OS 分发进行移植。&lt;/p&gt;
&lt;p&gt;容器因具有许多优势而变得流行起来。于是docker闪亮登场, 下面列出了容器的一些好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;敏捷应用程序的创建和部署：与使用 VM 镜像相比，提高了容器镜像创建的简便性和效率。&lt;/li&gt;
&lt;li&gt;持续开发、集成和部署：通过快速简单的回滚(由于镜像不可变性)，提供可靠且频繁的容器镜像构建和部署。&lt;/li&gt;
&lt;li&gt;关注开发与运维的分离：在构建/发布时而不是在部署时创建应用程序容器镜像，从而将应用程序与基础架构分离。&lt;/li&gt;
&lt;li&gt;可观察性不仅可以显示操作系统级别的信息和指标，还可以显示应用程序的运行状况和其他指标信号。&lt;/li&gt;
&lt;li&gt;跨开发、测试和生产的环境一致性：在便携式计算机上与在云中相同地运行。&lt;/li&gt;
&lt;li&gt;云和操作系统分发的可移植性：可在 Ubuntu、RHEL、CoreOS、本地、Google Engine 和其他任何地方运行。&lt;/li&gt;
&lt;li&gt;以应用程序为中心的管理：提高抽象级别，从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。&lt;/li&gt;
&lt;li&gt;松散耦合、分布式、弹性、解放的微服务：应用程序被分解成较小的独立部分，并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。&lt;/li&gt;
&lt;li&gt;资源隔离：可预测的应用程序性能。&lt;/li&gt;
&lt;li&gt;资源利用：高效率和高密度。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;容器是打包和运行应用程序的好方式。在生产环境中，您需要管理运行应用程序的容器，并确保不会停机。例如，如果一个容器发生故障，则需要启动另一个容器。如果系统处理此行为，会不会更容易？&lt;/p&gt;
&lt;p&gt;这就是 Kubernetes 的救援方法！&lt;/p&gt;
&lt;h1 id="2-kubernetes简介"&gt;2 Kubernetes简介&lt;/h1&gt;
&lt;p&gt;Kubernetes 是一个可移植的，可扩展的开源平台，用于管理容器化的工作负载和服务，方便了声明式配置和自动化。它拥有一个庞大且快速增长的生态系统。Kubernetes 的服务，支持和工具广泛可用。&lt;/p&gt;
&lt;h2 id="21-kubernetes-功能"&gt;2.1 Kubernetes 功能&lt;/h2&gt;
&lt;p&gt;Kubernetes 提供的功能：&lt;/p&gt;</description></item><item><title>Kubernetes设计架构</title><link>/2017/11/27/kubernetes%E8%AE%BE%E8%AE%A1%E6%9E%B6%E6%9E%84/</link><pubDate>Mon, 27 Nov 2017 00:00:00 +0000</pubDate><guid>/2017/11/27/kubernetes%E8%AE%BE%E8%AE%A1%E6%9E%B6%E6%9E%84/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;h1 id="kubernetes设计架构"&gt;Kubernetes设计架构&lt;/h1&gt;
&lt;p&gt;Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etc)，一切都基于分布式的存储系统。下面这张图是Kubernetes的架构图。&lt;/p&gt;
&lt;p&gt;&lt;img alt="k8s-architecture" loading="lazy" src="/2017/11/27/kubernetes%E8%AE%BE%E8%AE%A1%E6%9E%B6%E6%9E%84/k8s-architecture.png"&gt;&lt;/p&gt;
&lt;p&gt;Kubernetes主要由以下几个核心组件组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;etcd保存了整个集群的状态；&lt;/li&gt;
&lt;li&gt;apiserver提供了资源操作的唯一入口，并提供认证、授权、访问控制、API注册和发现等机制；&lt;/li&gt;
&lt;li&gt;controller manager负责维护集群的状态，比如故障检测、自动扩展、滚动更新等；&lt;/li&gt;
&lt;li&gt;scheduler负责资源的调度，按照预定的调度策略将Pod调度到相应的机器上；&lt;/li&gt;
&lt;li&gt;kubelet负责维护容器的生命周期，同时也负责Volume（CVI）和网络（CNI）的管理；&lt;/li&gt;
&lt;li&gt;Container runtime负责镜像管理以及Pod和容器的真正运行（CRI）；&lt;/li&gt;
&lt;li&gt;kube-proxy负责为Service提供cluster内部的服务发现和负载均衡；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除了核心组件，还有一些推荐的Add-ons：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kube-dns负责为整个集群提供DNS服务&lt;/li&gt;
&lt;li&gt;Ingress Controller为服务提供外网入口&lt;/li&gt;
&lt;li&gt;Heapster提供资源监控&lt;/li&gt;
&lt;li&gt;Dashboard提供GUI&lt;/li&gt;
&lt;li&gt;Federation提供跨可用区的集群&lt;/li&gt;
&lt;li&gt;Fluentd-elasticsearch提供集群日志采集、存储与查询&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kubernetes节点"&gt;Kubernetes节点&lt;/h2&gt;
&lt;p&gt;一个培训机构的kubernetes学习课程，用来参考做学习：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Chapter 1：课程介绍
理解 Kubernetes 设计原则、原理
了解 Kubernetes 的过去、现在和未来
了解并学会使用 Kubernetes 最重要的资源 -- API
学会如何创建和管理应用，并配置应用外部访问
理解 Kubernetes 网络、存储
掌握 Kubernetes 调度的原理和策略
Kubernetes 一些新功能的概念
了解 Kubernetes 的日志、监控方案
具备基本的故障排查的运维能力
Chapter 2：Kubernetes 基本概念
了解什么是 Kubernetes
了解 Kubernetes 的主要特性
理解为什么需要 Kubernetes
了解 Kubernetes 的过去、现在和未来
了解目前 Kubernetes 社区的情况和被采用情况
了解 Kubernetes 的基本架构
获得一些学习资料推荐
Chapter 3：Kubernetes 架构及原理
理解 Kubernetes 设计原则
深入理解 Kubernetes 集群中的组件及功能
了解 Kubernetes 集群对网络的预置要求
深入理解 Kubernetes 的工作原理
深入理解 Kubernetes 中 Pod 的设计思想
Chapter 4：Kubernetes 安装和配置
了解部署 Kubernetes 的多种方式
可以单机部署 Kubernetes（学习演示使用）
可以在宿主机部署一套 Kubernetes 集群（非生产使用）
Chapter 5：Kubernetes API 及集群访问
了解 Kubernetes 的 API
理解 Kubernetes 中 API 资源的结构定义
了解 kubectl 工具的使用
了解 Kubernetes 中 API 之外的其他资源
Chapter 6：ReplicaController，ReplicaSets 和 Deployments
理解 RC
理解 label 和 selector 的作用
理解 RS
理解 Deployments 并且可操作 Deployments
理解 rolling update 和 rollback
Chapter 7：Volume、配置文件及密钥
了解 Kubernetes 存储的管理，支持存储类型
理解 Pod 使用 volume 的多种工作流程以及演化
理解 pv 和 pvc 的原理
理解 storage class 的原理
理解 configmaps 的作用和使用方法
理解 secrets 的作用和使用方法资源结构
Chapter 8：Service 及服务发现
了解 Docker 网络和 Kubernetes 网络
了解 Flannel 和 Calico 网络方案
理解 Pod 在 Kubernetes 网络中的工作原理
理解 Kubernetes 中的 Service
理解 Service 在 Kubernetes 网络中的工作原理
理解 Kubernetes 中的服务发现
掌握 Kubernetes 中外部访问的几种方式
Chapter 9：Ingress 及负载均衡
理解 Ingress 和 Ingress controller 的工作原理
掌握如何创建 Ingress 规则
掌握如何部署 Ingress controller
Chapter 10：DaemonSets，StatefulSets，Jobs，HPA，RBAC
了解 DaemonSet 资源和功能
了解 StatefulSet 资源和功能
了解 Jobs 资源和功能
了解 HPA 资源和功能
了解 RBAC 资源和功能
Chapter 11：Kubernetes 调度
理解 Pod 调度的相关概念
深度理解 Kubernetes 调度策略和算法
深度理解调度时的 Node 亲和性
深度理解调度时的 Pod 亲和性和反亲和性
深度理解污点和容忍对调度的影响
深度理解强制调度 Pod 的方法
Chapter 12：日志、监控、Troubleshooting
理解 Kubernetes 集群的日志方案
理解 Kubernetes 集群的监控方案
了解相关开源项目：Heapster，Fluentd，Prometheus 等
掌握常用的集群，Pod，Service 等故障排查和运维手段
Chapter 13：自定义资源 CRD
理解和掌握 Kubernetes 中如何自定义 API 资源
可以通过 kubectl 管理 API 资源
了解用于自定义资源的 Controller 及相关使用示例
了解 TPR 和 CRD
Chapter 14：Kubernetes Federation
了解 Kubernetes 中 Federation 的作用和原理
了解 Federation 的创建过程
了解 Federation 支持的 API 资源
了解集群间平衡 Pod 副本的方法
Chapter 15：应用编排 Helm，Chart
了解 Kubernetes 中如何进行应用编排
了解 Helm 的作用和工作原理
了解 Tiller 的作用和工作原理
了解 Charts 的作用和工作原理
Chapter 16：Kubernetes 安全
了解 Kubernetes 中 API 访问过程
了解 Kubernetes 中的 Authentication
了解 Kubernetes 中的 Authorization
了解 ABAC 和 RBAC 两种授权方式
了解 Kubernetes 中的 Admission
了解 Pod 和容器的操作权限安全策略
了解 Network Policy 的作用和资源配置方法
&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>