Files
davidpaulyoung/public/2018/05/23/istio-auto-injection-with-webhook/index.html
David Young d0d428f3bf build site
2026-05-14 14:23:58 -06:00

827 lines
28 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
(function() {
const autoTheme = false;
if (autoTheme) {
document.documentElement.setAttribute('data-auto-theme', 'true');
}
const theme = localStorage.getItem('cleanwhite-theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', theme);
})();
</script>
<meta property="og:site_name" content="David Young">
<meta property="og:type" content="article">
<meta property="og:image" content="https://davidpaulyoung.com//img/2018-4-25-istio-auto-injection-with-webhook/lion.jpg">
<meta property="twitter:image" content="https://davidpaulyoung.com//img/2018-4-25-istio-auto-injection-with-webhook/lion.jpg" />
<meta name="title" content="Istio Sidecar自动注入原理" />
<meta property="og:title" content="Istio Sidecar自动注入原理" />
<meta property="twitter:title" content="Istio Sidecar自动注入原理" />
<meta name="description" content="Kubernets 1.9版本引入了Admission Webhook(web 回调)扩展机制通过Webhook,开发者可以非常灵活地对Kubernets API Server的功能进行扩展在API Server创建资源时对资源进行验证或者修改。 Istio 0.7版本就利用了Kubernets webhook实现了sidecar的自动注入。">
<meta property="og:description" content="Kubernets 1.9版本引入了Admission Webhook(web 回调)扩展机制通过Webhook,开发者可以非常灵活地对Kubernets API Server的功能进行扩展在API Server创建资源时对资源进行验证或者修改。 Istio 0.7版本就利用了Kubernets webhook实现了sidecar的自动注入。" />
<meta property="twitter:description" content="Kubernets 1.9版本引入了Admission Webhook(web 回调)扩展机制通过Webhook,开发者可以非常灵活地对Kubernets API Server的功能进行扩展在API Server创建资源时对资源进行验证或者修改。 Istio 0.7版本就利用了Kubernets webhook实现了sidecar的自动注入。" />
<meta property="og:url" content="https://davidpaulyoung.com/2018/05/23/istio-auto-injection-with-webhook/" />
<meta property="twitter:card" content="summary" />
<meta name="keyword" content="Von Balthasar, Scripture, Gravel Riding, Ham Radio, Divine Office, Open Source">
<link rel="shortcut icon" href="/img/favicon.ico">
<title>Istio Sidecar自动注入原理 | David Young Blog</title>
<link rel="canonical" href="/2018/05/23/istio-auto-injection-with-webhook/">
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/hugo-theme-cleanwhite.css">
<link rel="stylesheet" href="/css/theme-variables.css">
<link rel="stylesheet" href="/css/zanshang.min.css">
<link rel="stylesheet" href="/css/font-awesome.all.min.css">
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="/js/hux-blog.min.js"></script>
<script src="/js/lazysizes.min.js"></script>
</head>
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header page-scroll">
<button type="button" class="navbar-toggle">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">David Young</a>
</div>
<div id="huxblog_navbar">
<div class="navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/">All Posts</a>
</li>
<li>
<a href="/categories/life/">life</a>
</li>
<li>
<a href="/categories/tech/">tech</a>
</li>
<li>
<a href="/categories/tips/">tips</a>
</li>
<li><a href="/archive//">ARCHIVE</a></li>
<li><a href="/notes//">NOTES</a></li>
<li><a href="/about//">ABOUT</a></li>
<li>
<a href="/search"><i class="fa fa-search"></i></a>
</li>
<li>
<a href="#" id="theme-toggle" title="Toggle dark mode" style="opacity: 0;">
<i class="fa fa-moon"></i>
<i class="fa fa-sun" style="display: none;"></i>
</a>
</li>
<script>
(function() {
var theme = localStorage.getItem('cleanwhite-theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
var toggleBtn = document.getElementById('theme-toggle');
if (toggleBtn) {
var moonIcon = toggleBtn.querySelector('.fa-moon');
var sunIcon = toggleBtn.querySelector('.fa-sun');
if (theme === 'dark') {
if (moonIcon) moonIcon.style.display = 'none';
if (sunIcon) sunIcon.style.display = 'inline';
toggleBtn.setAttribute('title', 'Switch to light mode');
} else {
if (moonIcon) moonIcon.style.display = 'inline';
if (sunIcon) sunIcon.style.display = 'none';
toggleBtn.setAttribute('title', 'Switch to dark mode');
}
requestAnimationFrame(function() {
toggleBtn.style.transition = 'opacity 0.2s ease';
toggleBtn.style.opacity = '1';
});
}
})();
</script>
</ul>
</div>
</div>
</div>
</nav>
<script>
var $body = document.body;
var $toggle = document.querySelector('.navbar-toggle');
var $navbar = document.querySelector('#huxblog_navbar');
var $collapse = document.querySelector('.navbar-collapse');
$toggle.addEventListener('click', handleMagic)
function handleMagic(e){
if ($navbar.className.indexOf('in') > 0) {
$navbar.className = " ";
setTimeout(function(){
if($navbar.className.indexOf('in') < 0) {
$collapse.style.height = "0px"
}
},400)
}else{
$collapse.style.height = "auto"
$navbar.className += " in";
}
}
document.addEventListener('DOMContentLoaded', function() {
var navLinks = document.querySelectorAll('.navbar-collapse a');
navLinks.forEach(function(link) {
link.addEventListener('click', function() {
if ($navbar.className.indexOf('in') > 0) {
$navbar.className = " ";
setTimeout(function(){
if($navbar.className.indexOf('in') < 0) {
$collapse.style.height = "0px"
}
},400)
}
});
});
});
</script>
<style type="text/css">
header.intro-header {
background-image: url('/img/2018-4-25-istio-auto-injection-with-webhook/lion.jpg')
}
</style>
<header class="intro-header" >
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="post-heading">
<div class="tags">
<a class="tag" href="/tags/kubernetes" title="Kubernetes">
Kubernetes
</a>
<a class="tag" href="/tags/istio" title="Istio">
Istio
</a>
</div>
<h1>Istio Sidecar自动注入原理</h1>
<h2 class="subheading">Kubernetes webhook扩展机制解析</h2>
<span class="meta">
Posted by
    &#34;赵化冰&#34;
on
Wednesday, May 23, 2018
</span>
</div>
</div>
</div>
</div>
</header>
<article>
<div class="container">
<div class="row">
<div class="
col-lg-8 col-lg-offset-2
col-md-10 col-md-offset-1
post-container">
<h2 id="前言">前言</h2>
<hr>
<p>Kubernets 1.9版本引入了Admission Webhook(web 回调)扩展机制通过Webhook,开发者可以非常灵活地对Kubernets API Server的功能进行扩展在API Server创建资源时对资源进行验证或者修改。</p>
<p>使用webhook的优势是不需要对API Server的源码进行修改和重新编译就可以扩展其功能。插入的逻辑实现为一个独立的web进程通过参数方式传入到kubernets中由kubernets在进行自身逻辑处理时对扩展逻辑进行回调。</p>
<p>Istio 0.7版本就利用了Kubernets webhook实现了sidecar的自动注入。</p>
<h2 id="什么是admission">什么是Admission</h2>
<hr>
<p>Admission是Kubernets中的一个术语指的是Kubernets API Server资源请求过程中的一个阶段。如下图所示在API Server接收到资源创建请求时首先会对请求进行认证和鉴权然后经过Admission处理最后再保存到etcd。
<img src="/img/2018-4-25-istio-auto-injection-with-webhook/admission-phase.png" alt="">
从图中看到Admission中有两个重要的阶段Mutation和Validation这两个阶段中执行的逻辑如下</p>
<ul>
<li>
<p>Mutation</p>
<p>Mutation是英文“突变”的意思,从字面上可以知道在Mutation阶段可以对请求内容进行修改。</p>
</li>
<li>
<p>Validation</p>
<p>在Validation阶段不允许修改请求内容但可以根据请求的内容判断是继续执行该请求还是拒绝该请求。</p>
</li>
</ul>
<h2 id="admission-webhook">Admission webhook</h2>
<hr>
<p>通过Admission webhook,可以加入Mutation和Validation两种类型的webhook插件这些插件和Kubernets提供的预编译的Admission插件具有相同的能力。可以想到的用途包括</p>
<ul>
<li>修改资源。例如Istio就通过Admin Webhook在Pod资源中增加了Envoy sidecar容器。</li>
<li>自定义校验逻辑,例如对资源名称有一些特殊要求。或者对自定义资源的合法性进行校验。</li>
</ul>
<h2 id="采用webhook自动注入istio-sidecar">采用Webhook自动注入Istio Sidecar</h2>
<hr>
<h3 id="kubernets版本要求">Kubernets版本要求</h3>
<p>webhook支持需要Kubernets1.9或者更高的版本,使用下面的命令确认kube-apiserver的Admin webhook功能已启用。</p>
<pre tabindex="0"><code>kubectl api-versions | grep admissionregistration
admissionregistration.k8s.io/v1beta1
</code></pre><h3 id="生成sidecar-injection-webhook的密钥和证书">生成sidecar injection webhook的密钥和证书</h3>
<p>Webhook使用数字证书向kube-apiserver进行身份认证因此需要先使用工具生成密钥对并向Istio CA申请数字证书。</p>
<pre tabindex="0"><code>./install/kubernetes/webhook-create-signed-cert.sh /
--service istio-sidecar-injector /
--namespace istio-system /
--secret sidecar-injector-certs
</code></pre><h3 id="将生成的数字证书配置到webhook中">将生成的数字证书配置到webhook中</h3>
<pre tabindex="0"><code>cat install/kubernetes/istio-sidecar-injector.yaml | /
./install/kubernetes/webhook-patch-ca-bundle.sh &gt; /
install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml
</code></pre><h3 id="创建sidecar-injection-configmap">创建sidecar injection configmap</h3>
<pre tabindex="0"><code>kubectl apply -f install/kubernetes/istio-sidecar-injector-configmap-release.yaml
</code></pre><h3 id="部署sidecar-injection-webhook">部署sidecar injection webhook</h3>
<pre tabindex="0"><code>kubectl apply -f install/kubernetes/istio-sidecar-injector-with-ca-bundle.yaml
</code></pre><p>通过命令查看部署好的webhook injector</p>
<pre tabindex="0"><code>kubectl -n istio-system get deployment -listio=sidecar-injector
Copy
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
istio-sidecar-injector 1 1 1 1 1d
```
### 开启需要自动注入sidecar的namespace
```
kubectl label namespace default istio-injection=enabled
kubectl get namespace -L istio-injection
NAME STATUS AGE ISTIO-INJECTION
default Active 1h enabled
istio-system Active 1h
kube-public Active 1h
kube-system Active 1h
```
## 参考
* [Extensible Admission is Beta](https://kubernetes.io/blog/2018/01/extensible-admission-is-beta)
* [Installing the Istio Sidecar](https://istio.io/docs/setup/kubernetes/sidecar-injection.html)
</code></pre>
<div class="entry-shang text-center">
<p>「真诚赞赏,手留余香」</p>
<button class="zs show-zs btn btn-bred">赞赏支持</button>
</div>
<div class="zs-modal-bg"></div>
<div class="zs-modal-box">
<div class="zs-modal-head">
<button type="button" class="close">×</button>
<span class="author"><a href="https://davidpaulyoung.com/"><img src="/img/favicon.png" />David Young</a></span>
<p class="tip"><i></i><span>真诚赞赏,手留余香</span></p>
</div>
<div class="zs-modal-body">
<div class="zs-modal-btns">
<button class="btn btn-blink" data-num="2">2元</button>
<button class="btn btn-blink" data-num="5">5元</button>
<button class="btn btn-blink" data-num="10">10元</button>
<button class="btn btn-blink" data-num="50">50元</button>
<button class="btn btn-blink" data-num="100">100元</button>
<button class="btn btn-blink" data-num="1">任意金额</button>
</div>
<div class="zs-modal-pay">
<button class="btn btn-bred" id="pay-text">2元</button>
<p>使用<span id="pay-type">微信</span>扫描二维码完成支付</p>
<img src="/img/reward/wechat-2.png" id="pay-image"/>
</div>
</div>
<div class="zs-modal-footer">
<label><input type="radio" name="zs-type" value="wechat" class="zs-type" checked="checked"><span ><span class="zs-wechat"><img src="/img/reward/wechat-btn.png"/></span></label>
<label><input type="radio" name="zs-type" value="alipay" class="zs-type" class="zs-alipay"><img src="/img/reward/alipay-btn.png"/></span></label>
</div>
</div>
<script type="text/javascript" src="/js/reward.js"></script>
<hr>
<ul class="pager">
<li class="previous">
<a href="/2018/05/21/algolia-integration-with-jekyll/" data-toggle="tooltip" data-placement="top" title="使用Algolia为Gitpage博客提供站内搜索">&larr;
Previous Post</a>
</li>
<li class="next">
<a href="/2018/05/22/user_authentication_authorization/" data-toggle="tooltip" data-placement="top" title="微服务安全沉思录之一">Next
Post &rarr;</a>
</li>
</ul>
<link href="https://xxx.xxx.com/dist/Artalk.css" rel="stylesheet" />
<script src="https://xxx.xxx.com/dist/Artalk.js"></script>
<div id="Comments"></div>
<script>
Artalk.init({
el: '#Comments',
pageKey: 'https:\/\/davidpaulyoung.com\/2018\/05\/23\/istio-auto-injection-with-webhook\/',
pageTitle: 'Istio Sidecar自动注入原理',
server: 'https:\/\/xxx.xxx.com',
site: 'xxx blog',
})
</script>
</div>
<div class="
col-lg-2 col-lg-offset-0
visible-lg-block
sidebar-container
catalog-container">
<div class="side-catalog">
<hr class="hidden-sm hidden-xs">
<h5>
<a class="catalog-toggle" href="#">CATALOG</a>
</h5>
<ul class="catalog-body"></ul>
</div>
</div>
<div class="
col-lg-8 col-lg-offset-2
col-md-10 col-md-offset-1
sidebar-container">
<section>
<hr class="hidden-sm hidden-xs">
<h5><a href="/tags/">FEATURED TAGS</a></h5>
<div class="tags">
<a href="/tags/docker" title="docker">
docker
</a>
<a href="/tags/istio" title="istio">
istio
</a>
<a href="/tags/kubernetes" title="kubernetes">
kubernetes
</a>
<a href="/tags/microservice" title="microservice">
microservice
</a>
<a href="/tags/security" title="security">
security
</a>
<a href="/tags/service-mesh" title="service mesh">
service mesh
</a>
<a href="/tags/tips" title="tips">
tips
</a>
</div>
</section>
<section>
<hr>
<h5>FRIENDS</h5>
<ul class="list-inline">
<li><a target="_blank" href="https://zhaozhihan.com">Linda的博客</a></li>
</ul>
</section>
</div>
</div>
</div>
</article>
<footer>
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<ul class="list-inline text-center">
<li>
<a href="mailto:youremail@gmail.com">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fas fa-envelope fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li>
<a target="_blank" href="/your%20wechat%20qr%20code%20image">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-weixin fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li>
<a target="_blank" href="https://github.com/yourgithub">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-github fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li>
<a target="_blank" href="https://www.linkedin.com/in/yourlinkedinid">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-linkedin fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li>
<a target="_blank" href="https://stackoverflow.com/users/yourstackoverflowid">
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fab fa-stack-overflow fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
<li>
<a href='' rel="alternate" type="application/rss+xml" title="David Young" >
<span class="fa-stack fa-lg">
<i class="fas fa-circle fa-stack-2x"></i>
<i class="fas fa-rss fa-stack-1x fa-inverse"></i>
</span>
</a>
</li>
</ul>
<p class="copyright text-muted">
Copyright &copy; David Young 2026
<br>
<a href="https://themes.gohugo.io/hugo-theme-cleanwhite">CleanWhite Hugo Theme</a> by <a href="https://zhaohuabing.com">Huabing</a> |
<iframe
style="margin-left: 2px; margin-bottom:-5px;"
frameborder="0" scrolling="0" width="100px" height="20px"
src="https://ghbtns.com/github-btn.html?user=zhaohuabing&repo=hugo-theme-cleanwhite&type=star&count=true" >
</iframe>
</p>
</div>
</div>
</div>
</footer>
<script>
function loadAsync(u, c) {
var d = document, t = 'script',
o = d.createElement(t),
s = d.getElementsByTagName(t)[0];
o.src = u;
if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
s.parentNode.insertBefore(o, s);
}
</script>
<script>
if($('#tag_cloud').length !== 0){
loadAsync("/js/jquery.tagcloud.js",function(){
$.fn.tagcloud.defaults = {
color: {start: '#bbbbee', end: '#0085a1'},
};
$('#tag_cloud a').tagcloud();
})
}
</script>
<script>
(function() {
function updateTagcloudColors() {
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
const startColor = isDark ? '#808080' : '#bbbbee';
if($('#tag_cloud').length !== 0 && $.fn.tagcloud) {
$.fn.tagcloud.defaults = {
color: {start: startColor, end: '#0085a1'},
};
$('#tag_cloud a').tagcloud();
}
}
$(document).ready(function() {
updateTagcloudColors();
});
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === 'data-theme') {
updateTagcloudColors();
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme']
});
})();
</script>
<script>
loadAsync("https://cdn.jsdelivr.net/npm/fastclick@1.0.6/lib/fastclick.min.js", function(){
var $nav = document.querySelector("nav");
if($nav) FastClick.attach($nav);
})
</script>
<script src="/js/theme-toggle.js"></script>
<script type="text/javascript">
function generateCatalog(selector) {
_containerSelector = 'div.post-container'
var P = $(_containerSelector), a, n, t, l, i, c;
a = P.find('h1,h2,h3,h4,h5,h6');
$(selector).html('')
a.each(function () {
n = $(this).prop('tagName').toLowerCase();
i = "#" + $(this).prop('id');
t = $(this).text();
c = $('<a href="' + i + '" rel="nofollow" title="' + t + '">' + t + '</a>');
l = $('<li class="' + n + '_nav"></li>').append(c);
$(selector).append(l);
});
return true;
}
generateCatalog(".catalog-body");
$(".catalog-toggle").click((function (e) {
e.preventDefault();
$('.side-catalog').toggleClass("fold")
}))
loadAsync("\/js\/jquery.nav.js", function () {
$('.catalog-body').onePageNav({
currentClass: "active",
changeHash: !1,
easing: "swing",
filter: "",
scrollSpeed: 700,
scrollOffset: 0,
scrollThreshold: .2,
begin: null,
end: null,
scrollChange: null,
padding: 80
});
});
</script>
</body>
</html>