|
|
楼主 |
发表于 2025-1-1 19:51:59
|
显示全部楼层
创建目录
+ x- @0 ?4 W- n: Z8 e8 r根据自身实际情况创建指定路径,此路径用来存放k8s二进制文件以及用到的镜像文件
/ ~; G3 s8 h( ^( D+ U$ z8 |8 I: x% J1 V/ _1 U: w$ D
mkdir -p /approot1/k8s/{bin,images,pkg,tmp/{ssl,service}}
& ^! { P5 s$ Y关闭防火墙
P( ]7 z o9 z* afor i in 192.168.91.19 192.168.91.20;do \
! L% n% w6 B; j" _1 E; B( p" jssh $i "systemctl disable firewalld"; \" V3 ]3 M L& I: C' E3 N
ssh $i "systemctl stop firewalld"; \
; i( y6 a/ }: v4 r" P5 q+ rdone" W2 m( Z/ D. t+ O/ l R9 q
关闭selinux
9 V( \$ s, [( @9 K5 i; K+ _7 Q临时关闭
1 y$ k/ I0 Y5 y4 S- C }
V" | W" v4 c2 u# K7 Efor i in 192.168.91.19 192.168.91.20;do \
/ ]5 `, ~% M* b9 ^ssh $i "setenforce 0"; \
) P& H" y( Z/ P0 A" B1 G0 g2 Vdone h$ u* L; w) f, g- ?8 c( X# {
永久关闭
" `3 ]+ |9 u% ?" f/ u, y
3 V8 }) X9 G! Ofor i in 192.168.91.19 192.168.91.20;do \
- v6 F" ?+ A/ g3 y) f. j8 T& u7 z, Rssh $i "sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config"; \+ e3 `- c& s, e! r0 R
done+ c7 f9 z$ ]7 T8 i. K( b" G
关闭swap/ h; P" q( U) q8 f ]) a
临时关闭
' j- T( j) Q# ?3 s/ Y
. k" V( \0 y( M" wfor i in 192.168.91.19 192.168.91.20;do \
9 \+ w2 X$ F: v+ Y* dssh $i "swapoff -a"; \ B5 g( ]( Y# B, m
done
8 t1 }% S+ j0 b% M* A; o永久关闭& O, `4 h E! {+ N. l0 t/ ~7 I
/ i U' [9 }& Y; U+ W; x# n
for i in 192.168.91.19 192.168.91.20;do \* x3 L& s; M m; V
ssh $i "sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab"; \5 S1 a% I& Q0 e& }
done
& [4 b, y; Y5 x) \( b- t! |开启内核模块9 P& a- p6 ^1 R, V
临时开启, p$ t; [9 M; y4 {2 u; d; L7 H
7 b) z! p- |3 h) gfor i in 192.168.91.19 192.168.91.20;do \
T* `" Z$ y4 `; d3 `ssh $i "modprobe ip_vs"; \
3 P: Q* R, Y9 O; c, R jssh $i "modprobe ip_vs_rr"; \2 }0 Y0 r% Q( M; B5 c p1 @
ssh $i "modprobe ip_vs_wrr"; \
D6 O- N9 L4 q& T9 P5 }3 H; Fssh $i "modprobe ip_vs_sh"; \
2 |4 @6 c9 D! o4 E4 _* M1 a5 Dssh $i "modprobe nf_conntrack"; \
" {) ` R- z5 X+ Bssh $i "modprobe nf_conntrack_ipv4"; \
" V) O( l1 x- L5 I# n7 Fssh $i "modprobe br_netfilter"; \
! z; I T& a$ v0 s9 U4 C- Issh $i "modprobe overlay"; \, _; v) t) E' D8 y, O* N# x
done
- Z1 h9 i7 D6 ]8 ~; r; c永久开启
0 j" d8 W# E; I6 b; x$ {* q1 x
- b" |$ f7 W* r& t" avim /approot1/k8s/tmp/service/k8s-modules.conf
" y3 y3 g9 a7 q# T% Aip_vs* ?5 W) r' f$ \9 r8 W1 }% E
ip_vs_rr
- Z% K2 `( g6 [2 R/ h9 l+ jip_vs_wrr2 m9 Y- p& E! @% Q6 J0 `
ip_vs_sh
$ V7 N6 e$ ?! z) lnf_conntrack
! V9 S% a- e6 J$ gnf_conntrack_ipv4+ ?- b Z5 j3 D9 g! @1 s) {2 R
br_netfilter l) z l' z) O
overlay
5 P% s# P: g' A) t$ p& |. z分发到所有节点. I- j6 }8 Z1 G o! h7 `
for i in 192.168.91.19 192.168.91.20;do \) p/ ?! ]* f5 a
scp /approot1/k8s/tmp/service/k8s-modules.conf $i:/etc/modules-load.d/; \. t. c1 P4 N7 c# ]4 M; ^
done( a' e" p& N6 |3 X0 d
启用systemd自动加载模块服务
+ p" S" t& s' Y- ^3 Nfor i in 192.168.91.19 192.168.91.20;do \, T, j. S6 q4 {
ssh $i "systemctl enable systemd-modules-load"; \
+ t+ {" L3 o O& d L2 w" pssh $i "systemctl restart systemd-modules-load"; \! C1 l6 z- o9 F
ssh $i "systemctl is-active systemd-modules-load"; \
1 d$ L6 S3 r$ Y @1 S" @9 ]done! o/ V' w- U$ v) q* m# b
返回active表示 自动加载模块服务 启动成功2 g+ u* O+ m# P% {; J- N
4 m$ g; C/ a+ m( C! h" \
配置系统参数
) Q7 J0 v4 C9 `; n以下的参数适用于3.x和4.x系列的内核
) Z* A' ^" s4 g2 w& D2 |2 N9 i3 F! t' s X% e6 a# M
vim /approot1/k8s/tmp/service/kubernetes.conf
( ^$ `7 R( I6 r2 m建议编辑之前,在 vim 里面先执行 :set paste ,避免复制进去的内容和文档的不一致,比如多了注释,或者语法对齐异常
0 u4 ~% n* t0 R2 z
7 Y- J# r% O3 d8 B# 开启数据包转发功能(实现vxlan)# ]' T H6 k% I8 i/ D& h
net.ipv4.ip_forward=13 b/ a' [ |* l$ k/ `
# iptables对bridge的数据进行处理 ~( H @6 D5 N+ v! M
net.bridge.bridge-nf-call-iptables=1
: A* b% N, }( O3 D+ t% [, Mnet.bridge.bridge-nf-call-ip6tables=17 |: Y {- J) [2 a. y- _ k
net.bridge.bridge-nf-call-arptables=19 G g. g; p3 r: E
# 关闭tcp_tw_recycle,否则和NAT冲突,会导致服务不通
, ]9 o' a! T4 [4 Y. gnet.ipv4.tcp_tw_recycle=03 b1 T7 c& n1 t6 e n1 D5 V
# 不允许将TIME-WAIT sockets重新用于新的TCP连接
( a# U/ I3 t$ l/ c" {9 ^net.ipv4.tcp_tw_reuse=0: X" x. G! L+ w0 d. D- K
# socket监听(listen)的backlog上限3 q R2 B3 {- J7 u/ l) b/ {
net.core.somaxconn=327683 a) T) @/ Y2 X- `5 A# B' B9 a8 |
# 最大跟踪连接数,默认 nf_conntrack_buckets * 4
; Q6 e& Z- }3 ~( vnet.netfilter.nf_conntrack_max=1000000' k& Y. n) G& x4 ?* n* i |
# 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
3 y: b8 h, T6 Q9 ]8 e% _/ m7 E+ Hvm.swappiness=0% n; I0 K! q" s
# 计算当前的内存映射文件数。
1 `" t( f6 a( x8 q; N7 j) B: h Tvm.max_map_count=655360& m# f7 T5 \1 `) _$ N8 W/ X
# 内核可分配的最大文件数# w6 f0 ~9 I* Z8 Q' b/ G
fs.file-max=65536006 N7 V( {7 e: I
# 持久连接
) ]; A9 D7 m- d6 O) Knet.ipv4.tcp_keepalive_time=600$ i6 K3 A2 E X3 f! w5 p
net.ipv4.tcp_keepalive_intvl=30
4 Z! ?4 \$ } y- b5 w" Bnet.ipv4.tcp_keepalive_probes=10
" r N( B; @$ k* ]4 J& t分发到所有节点
' ~" ~5 v2 e' N2 H8 U+ G- s% S" Xfor i in 192.168.91.19 192.168.91.20;do \, O0 k- T8 F( y) ]6 ^: B l6 k
scp /approot1/k8s/tmp/service/kubernetes.conf $i:/etc/sysctl.d/; \
0 z* d$ j, {, @% rdone
& i2 I i1 L* p% \# q, y& R加载系统参数
4 W& Y; s- x9 {8 `for i in 192.168.91.19 192.168.91.20;do \( V" g; I5 m- q1 j' f
ssh $i "sysctl -p /etc/sysctl.d/kubernetes.conf"; \' ]3 }1 B0 E( E8 s
done
0 o* e8 x, j2 [* P% P9 s8 z清空iptables规则0 ?; H/ \3 E0 `& h/ G1 U( T
for i in 192.168.91.19 192.168.91.20;do \9 v) q$ u, t5 p) ~$ w0 h
ssh $i "iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat"; \1 j. ]! @! ~2 Y1 k( b
ssh $i "iptables -P FORWARD ACCEPT"; \
. p; m$ f2 ^2 \% E, J* \ Sdone7 x: D5 U' o: k8 p
配置 PATH 变量8 h/ H5 i2 K+ |3 M M7 w1 E. b
for i in 192.168.91.19 192.168.91.20;do \
: ^! y, q3 T3 }6 }; kssh $i "echo 'PATH=$PATH:/approot1/k8s/bin' >> $HOME/.bashrc"; \
, D" N' Z1 ~9 k$ ]5 Ddone
7 d- K' b. a' Fsource $HOME/.bashrc) M9 V4 f3 F# Y7 ]; P. G0 q0 z
下载二进制文件
1 x& |; y, ?# S7 @其中一台节点操作即可
( B& v6 i, F( f/ i/ F4 c: g' q/ d3 d/ a1 u! T
github下载会比较慢,可以从本地上传到 /approot1/k8s/pkg/ 目录下
- d! D; n P; ^1 O0 K; r# K" E' p5 I* o/ K' a
wget -O /approot1/k8s/pkg/kubernetes.tar.gz \
- |5 P: @: Y- m8 Q1 nhttps://dl.k8s.io/v1.23.3/kubernetes-server-linux-amd64.tar.gz [! ~; z- N( g2 v1 U+ w
# U. l# ^( `, {" dwget -O /approot1/k8s/pkg/etcd.tar.gz \. [5 g3 T! w1 O7 l6 c
https://github.com/etcd-io/etcd/ ... -linux-amd64.tar.gz' Y9 D3 Q0 `* Z6 A, l
解压并删除不必要的文件) Z% L" W' P; \% @/ m
% M3 W% u% K1 C/ q7 q
cd /approot1/k8s/pkg/$ w# h* u2 \- T: `* ^
for i in $(ls *.tar.gz);do tar xvf $i && rm -f $i;done0 V# V4 E% ]2 o# {9 {
mv kubernetes/server/bin/ kubernetes/- i4 S* k8 b, v2 F5 R6 u8 [1 n
rm -rf kubernetes/{addons,kubernetes-src.tar.gz,LICENSES,server}
, Z9 t" L1 T3 K, f1 Y krm -f kubernetes/bin/*_tag kubernetes/bin/*.tar. P/ f& M( U0 `+ h5 m
rm -rf etcd-v3.5.1-linux-amd64/Documentation etcd-v3.5.1-linux-amd64/*.md
$ f* R3 M1 ^9 R) k9 k0 h9 t6 m9 S8 j部署 master 节点0 @+ f# y9 }1 {% \9 b
创建 ca 根证书
8 v/ E9 r7 i8 {8 U/ jwget -O /approot1/k8s/bin/cfssl https://github.com/cloudflare/cf ... l_1.6.1_linux_amd64
6 x6 i- u1 v$ I' g& awget -O /approot1/k8s/bin/cfssljson https://github.com/cloudflare/cf ... n_1.6.1_linux_amd64
* P. [+ p% {+ w- Y9 Nchmod +x /approot1/k8s/bin/*/ H! |8 X- ^7 Q: M% }
vim /approot1/k8s/tmp/ssl/ca-config.json
" } \9 N; V { c8 Q{+ S7 ?& R* m1 v! ?! @+ [
"signing": {1 r! A3 c8 U4 b/ |! d
"default": {
" d& I- Z+ c6 h* b% ~ "expiry": "87600h"( Q* R6 o1 i+ P3 o8 j$ t
},
- v- l4 j! v1 d& Z# G "profiles": {
; T" |8 F5 p9 r "kubernetes": {
7 ]8 l- d' G8 o* p: F8 e. B "usages": [
; X% o- h, n/ z( j0 H% {5 \) [ "signing",
* ^1 x; ]" q7 J8 Y6 M: X "key encipherment",+ r" t* H2 D6 ^" S
"server auth",2 j" ]; c. U/ r1 @# a( H" u
"client auth"7 Q6 e. O! T6 v& S
],
8 d3 ?4 |5 ?4 i& A/ v* H0 t; m "expiry": "876000h"
2 X2 D$ ~* A7 n3 E) F0 ?; `3 c( u }: q4 e9 U6 r0 ^" W W4 |2 F
}% X) @9 P' ~. T
}# p4 H" J' N3 b7 g$ v
}/ j$ H2 B+ R* W O5 Y& c' P
vim /approot1/k8s/tmp/ssl/ca-csr.json/ I6 M9 _# `$ z8 { B& S# z/ G
{. Q2 I1 m0 A$ X8 E) A
"CN": "kubernetes",& J- f7 f) L, T2 `5 y. o
"key": {2 y; K0 h1 a. K5 ^4 X
"algo": "rsa",* W' g* v v. h0 h
"size": 2048, O+ p0 |/ F& |" ~9 x. ~3 ]
}, S" s" {5 f/ M' w; W: P" [) @
"names": [: Q" m8 y; l9 q* L+ A: c2 e2 G6 q
{1 j: n; @$ a7 a
"C": "CN",
" Y7 k; _7 v& T, h4 l) D: u "ST": "ShangHai",
; T, v! ~2 [2 y "L": "ShangHai",
" J7 ?# D7 e. r0 W7 n "O": "k8s",- b; L% d. [$ b7 M/ {6 _7 Z
"OU": "System"
E6 c, y0 A! Y }* V) h z& H- D. C9 d
],/ c, i/ a* X% s3 v4 u+ A
"ca": {6 J J) J; X a! e
"expiry": "876000h"
5 J9 i! R3 c' { }9 p4 R5 W' _2 W' x6 r
}
/ r& O" S8 \0 o$ Ccd /approot1/k8s/tmp/ssl/3 f! _) N: ?" z) e& q k, z% `
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
3 F$ V& X+ s) w: ?& P/ e部署 etcd 组件
1 C* k6 S. L+ [+ L7 |创建 etcd 证书
" g/ {5 N+ G( d- ]5 F5 Xvim /approot1/k8s/tmp/ssl/etcd-csr.json3 e$ Z" Y$ w' W
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴
9 w% V. Z/ _+ r" S# ~( m' J0 _3 L0 D" W7 _
注意json的格式 x" V# W0 A2 |% U/ l' R
, X( e! w) f& }9 P" V9 o# y9 g) I
{# x e$ u" k. k
"CN": "etcd",
1 i8 r6 Z# |* m, R1 u! Y) p "hosts": [4 w2 P, N$ r7 K2 t
"127.0.0.1",
1 Z# j8 [6 y! W& [) g" u "192.168.91.19"
' [: |/ @5 i6 t# J2 [ ],' W [5 Q$ ?+ ^7 P$ ~
"key": {, s1 H6 C2 d6 t/ g
"algo": "rsa",1 I5 |/ ?' o$ H$ ^' ]- U! l1 F0 f% P
"size": 2048
6 w; `/ a+ y2 I# M6 h! g5 W },7 E8 }1 L1 R& J7 Q& C3 n: t7 Q
"names": [4 V% ^. X* F: h# ]
{
: |5 y0 e5 \) p$ `6 n0 L4 j "C": "CN",
, n: W0 @0 P# L4 p2 K "ST": "ShangHai",% Y8 f) V, C# O
"L": "ShangHai",; \% o( `% @4 i: I
"O": "k8s",
1 H- K6 G2 z5 z( |7 y7 [ "OU": "System"
: j; X& T6 s( g2 c }4 B; U! ^. O9 }
]
$ |: I* W" g* ?# k0 t}
* A% @/ k0 U0 p* rcd /approot1/k8s/tmp/ssl/- X/ \7 ]4 f3 S+ c' D
cfssl gencert -ca=ca.pem \, j* |/ C5 p% E: t1 `/ l
-ca-key=ca-key.pem \
. d. u! E' d7 u9 H: `-config=ca-config.json \
4 G0 o6 {1 J' V9 Y2 N2 G! k H-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
2 G1 q8 B& ^3 _5 {配置 etcd 为 systemctl 管理! `/ b* J E9 Z2 g; g
vim /approot1/k8s/tmp/service/kube-etcd.service.192.168.91.19( H3 L& ~1 {5 k- ^% S
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴* _: u% O: {' v- n8 V
% Q5 A- w& p9 W1 k" H) z
etcd 参数
; a0 ~& J% @' @; l$ f" x8 Z- W; {: Y
[Unit], {: I9 p, l$ u5 B
Description=Etcd Server
- a+ L+ @3 W4 j+ I2 nAfter=network.target
* c" B4 h+ B p# d& V9 s1 r3 AAfter=network-online.target
" H! M9 n4 a% SWants=network-online.target+ j. [4 Z ?9 Q0 A9 d( p8 x( F
Documentation=https://github.com/coreos1 c \; C2 `! ~! a) [9 `+ [6 h1 f
; A! v1 o5 ]8 t" B% W[Service]/ o; d# g5 N$ ?$ n& z; Q Y6 P
Type=notify
2 n% x& }. b- T/ i6 ^/ G( JWorkingDirectory=/approot1/k8s/data/etcd7 z1 O! a! n. M% J& U0 x( m
ExecStart=/approot1/k8s/bin/etcd \6 r0 O/ J5 W1 x8 |0 J8 |
--name=etcd-192.168.91.19 \
' W0 w+ Y D5 o/ j, L; x( t --cert-file=/etc/kubernetes/ssl/etcd.pem \0 M% u6 q7 Q. B4 y0 D; r# S
--key-file=/etc/kubernetes/ssl/etcd-key.pem \
5 y% u9 s3 w* }! {9 w --peer-cert-file=/etc/kubernetes/ssl/etcd.pem \% A7 D% u3 c! N- _8 l2 I
--peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \
6 B. F) T% b2 ] --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \* e" P1 V) z& d* k- h
--peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \
, |- J; c. B" q3 j8 d" W --initial-advertise-peer-urls=https://192.168.91.19:2380 \( S3 Q C' i6 L7 G6 p
--listen-peer-urls=https://192.168.91.19:2380 \7 k) ~/ k# ]6 [2 S/ e8 m
--listen-client-urls=https://192.168.91.19:2379,http://127.0.0.1:2379 \$ g6 P7 O- B$ Y/ A
--advertise-client-urls=https://192.168.91.19:2379 \" o- J) ^+ _ z( d) q
--initial-cluster-token=etcd-cluster-0 \
2 M+ X z7 T, ?/ {. J --initial-cluster=etcd-192.168.91.19=https://192.168.91.19:2380 \
) q$ `: n5 x5 ~* p# C/ _ --initial-cluster-state=new \
. J/ s6 W: ~" h5 R% p9 s3 L --data-dir=/approot1/k8s/data/etcd \
* Q0 n6 M$ m3 ?$ R --wal-dir= \
, Y) C3 q8 b7 D' F/ Y --snapshot-count=50000 \" W% s }; ? C- H; E6 ?, v6 ]
--auto-compaction-retention=1 \
- _2 H# n+ ^+ l; F8 R+ l( y --auto-compaction-mode=periodic \
0 g* ~ c5 T7 f$ z$ Y+ J* ? --max-request-bytes=10485760 \7 Y: g7 O3 o. |+ U8 h# ~
--quota-backend-bytes=8589934592
: A' N r2 t6 g. y( U' z2 v( rRestart=always7 Q/ C3 |" g* [0 b1 i4 w9 H
RestartSec=15' \0 x I/ |% C8 p# v
LimitNOFILE=65536- |3 `5 h& ^* U0 [
OOMScoreAdjust=-9997 }3 k$ k- b4 A! A$ |
: A$ f! U7 a7 d, u
[Install]
' q3 h' q v: W1 U8 [" H9 j! I' oWantedBy=multi-user.target* p' O) Y$ A( k* G) V' s* ]8 ]
分发证书以及创建相关路径# w( w" u X6 `; ?
如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制8 a7 j" W7 w% K3 X
% q! V3 y. k' d* [* h对应的目录也要确保和自己规划的一致,如果和我的有不同,注意修改,否则服务会启动失败& w% K) Z2 x8 G7 s" u0 }- J7 g+ u
' ~0 f: e' |3 N1 x$ W* d) ?7 V
for i in 192.168.91.19;do \4 N+ {, d; Z' u% s
ssh $i "mkdir -p /etc/kubernetes/ssl"; \
0 @2 g8 i4 _# }7 j9 r8 I4 sssh $i "mkdir -m 700 -p /approot1/k8s/data/etcd"; \
6 A/ D) G" X3 T. s# t: p3 Ussh $i "mkdir -p /approot1/k8s/bin"; \
t4 w( C! p, g1 M' ?$ jscp /approot1/k8s/tmp/ssl/{ca*.pem,etcd*.pem} $i:/etc/kubernetes/ssl/; \4 j& O% W+ T. g" [7 \1 Q, Z. c4 v
scp /approot1/k8s/tmp/service/kube-etcd.service.$i $i:/etc/systemd/system/kube-etcd.service; \
% [, A& Q6 u/ Nscp /approot1/k8s/pkg/etcd-v3.5.1-linux-amd64/etcd* $i:/approot1/k8s/bin/; \' S! e; l4 t' U5 m8 r( S$ _
done
& n6 [1 o' A6 Y8 s! u6 f! ], t启动 etcd 服务8 W6 a+ g. o( H# E
如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制
# Z- v9 w) ^, W- s; r7 o
, I( Z6 _2 j+ Z% I# m! M+ ?% ffor i in 192.168.91.19;do \/ S2 e) u' A8 v8 B; o
ssh $i "systemctl daemon-reload"; \
& ~" ?" n+ p2 @( Z [$ l. Nssh $i "systemctl enable kube-etcd"; \# x; n+ i. |/ H: y: L
ssh $i "systemctl restart kube-etcd --no-block"; \4 P9 R J2 H9 I9 l% w Z5 x$ ], U' w
ssh $i "systemctl is-active kube-etcd"; \6 s A5 e1 ^& b) G h8 J4 ?0 ^
done, [! W" S) y0 U1 C* X! R
返回 activating 表示 etcd 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19;do ssh $i "systemctl is-active kube-etcd";done
. ?( ~% R, }3 ^7 _
* A& b* h8 g# w8 @1 p返回active表示 etcd 启动成功,如果是多节点 etcd ,其中一个没有返回active属于正常的,可以使用下面的方式来验证集群
3 M& d( ?2 s7 h7 Z$ }9 h9 ^1 ]+ Y/ n
' x9 O" f R$ ?5 ~" D0 a6 k如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制
9 V; w0 |! k* M1 {" J% B/ q5 C3 f2 ~5 q7 x( }/ l
for i in 192.168.91.19;do \, r9 n: U9 H/ o9 K
ssh $i "ETCDCTL_API=3 /approot1/k8s/bin/etcdctl \8 C7 e" P7 m# f
--endpoints=https://${i}:2379 \! q' m0 w& f) s. q% }1 S+ Y
--cacert=/etc/kubernetes/ssl/ca.pem \
6 k9 S& z8 Z6 V' a --cert=/etc/kubernetes/ssl/etcd.pem \
b& N7 L) `; Z1 e --key=/etc/kubernetes/ssl/etcd-key.pem \
' o4 V2 T. A9 L endpoint health"; \
1 c& _& o- ^% R) S* G" ]" f$ Vdone. J6 c; R" m+ s) ?9 e" S/ D
https://192.168.91.19:2379 is healthy: successfully committed proposal: took = 7.135668ms
. i5 ?3 s8 f- o/ E
9 W+ m9 q: I1 Z; u: @2 y6 E返回以上信息,并显示 successfully 表示节点是健康的) {" e" u; `! B! d- a: D
. X5 `- Q0 e! W部署 apiserver 组件
+ ]0 \" x: ~. E. J* a( U' s创建 apiserver 证书
, k5 M2 S% S. _/ k7 q1 R$ b5 Pvim /approot1/k8s/tmp/ssl/kubernetes-csr.json( B$ k! }# X' C7 f
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴# ^9 K: w. G9 Y4 d/ J* ^) e. L* k
6 `2 s w- w( e注意json的格式4 d- ]. O8 a5 k) R$ b
4 x: c& F+ K& N' }6 S10.88.0.1 是 k8s 的服务 ip,千万不要和现有的网络一致,避免出现冲突
! ?& F4 {3 B2 e* z( X" s8 l/ H! x9 s3 }7 @( }4 L( Y4 _ C
{
; \9 f/ i) e# C0 [9 p" t "CN": "kubernetes",
/ J% l" c6 n6 C1 P "hosts": [9 R2 N* _) @, m
"127.0.0.1",
% P# R4 ?& n. |3 ` "192.168.91.19",- t$ I3 z- H3 o @; d- Z( e: d6 q
"10.88.0.1",
5 E3 B* K j9 ]5 _* k "kubernetes",
- k. q/ g2 G' V+ h$ m "kubernetes.default",
/ S* Z. V F4 v+ i1 W) { "kubernetes.default.svc",
G& T8 |1 a+ O- k8 f "kubernetes.default.svc.cluster",
5 O" B! N1 R3 y! v/ M1 b0 ^ "kubernetes.default.svc.cluster.local"( K; B% O" F, \& _# Z1 o
],
7 v+ `2 ^$ u t+ C "key": {; X$ H2 h. t1 {7 s
"algo": "rsa",' K' b9 u$ O- A9 \, n5 S0 _
"size": 20488 \2 x4 j: j/ n( y; ]- e! z# T3 H
},
# M2 o* ?# S/ a "names": [$ v2 z" G: {6 l3 `$ W b8 c. P/ Q
{
6 `3 M; }) S: O+ H+ K "C": "CN",2 I# s/ K5 v+ q- D$ y5 |
"ST": "ShangHai",2 o+ o. A2 r. x" M
"L": "ShangHai",* m) A7 B! v$ D
"O": "k8s",( ]* v) h Q ^* F o+ x) g
"OU": "System"
& g1 F% \! C# e1 D/ O }+ X# s2 z6 I0 O( [! K# e' }
]5 z5 k; [) T9 L" C- `5 b& Z$ |
}4 I3 c; ]6 T% J. r: H5 N6 T
cd /approot1/k8s/tmp/ssl/
) B" ~1 j. J( @cfssl gencert -ca=ca.pem \3 h9 {3 k$ n" C0 }0 T7 a
-ca-key=ca-key.pem \
3 Y8 u9 P6 u2 V+ d! e-config=ca-config.json \) k) [3 Y6 M+ g2 g
-profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
6 Y. B$ I) v. u' f创建 metrics-server 证书6 m* @, b+ M* V: L% ]/ W! x: t
vim /approot1/k8s/tmp/ssl/metrics-server-csr.json! H Z- ?3 i2 M% T: P" ]( @' p
{* t9 c) `0 Z2 Z
"CN": "aggregator",: U3 z' C& w, A4 ?# U
"hosts": [9 C; W" z& R4 w( }
],* J" O0 |6 ~% Q# d/ E0 O( ?: X
"key": {% l3 P2 g) s) C; l1 ~1 Y
"algo": "rsa",
H9 x$ T& s) r B' Z "size": 2048
7 j: e* v, o- y* q' s7 c) p) I },
5 q/ `+ l4 @% n @" h) o "names": [
7 x9 X% [# R y: z {
) x4 P# z3 ]. u1 H- r "C": "CN",
! R6 t/ k9 o$ |, z9 B }) P "ST": "ShangHai",
8 A1 B' s: I: K$ }4 H/ B "L": "ShangHai",
* b$ E" ]) P2 |+ W! u d "O": "k8s",( [/ C I5 o* P2 c7 M. f1 a6 m
"OU": "System"
2 [( \2 ?) M8 H' O# w( V8 X }$ e' r3 X& x8 s$ x3 K
]: ]4 y! k# o+ o! Q* ]
}9 [% M+ Q4 o( v4 ^. b
cd /approot1/k8s/tmp/ssl/6 v+ F$ B) U. M% }, Y; O- l
cfssl gencert -ca=ca.pem \
; {$ }: ^: r; p-ca-key=ca-key.pem \
9 H+ y- g- T Z$ |% K4 ^+ ?-config=ca-config.json \# c: ` c& q9 F
-profile=kubernetes metrics-server-csr.json | cfssljson -bare metrics-server; s; W) r( g, P# n% l
配置 apiserver 为 systemctl 管理* p% a$ a3 f+ p; S8 b
vim /approot1/k8s/tmp/service/kube-apiserver.service.192.168.91.192 Z6 ?$ O" |- C3 Z
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴
5 i0 }7 h6 B! |6 E0 R% q1 g$ t$ m1 O
' ?; X( [- g; }3 ]- |% g% S- T! }--service-cluster-ip-range 参数的 ip 网段要和 kubernetes-csr.json 里面的 10.88.0.1 是一个网段的) I0 M/ S* J; H& ` X0 ?7 L
1 G+ [7 _' I d# q6 y/ S+ w
--etcd-servers 如果 etcd 是多节点的,这里要写上所有的 etcd 节点
+ f1 O, m3 N4 J( p9 a. Q, S
5 A% g: q. e% l0 napiserver 参数
S* }: ^4 j2 u% d+ B
: H2 Y; B6 b! r( g[Unit]
! j2 @4 @3 l/ d& vDescription=Kubernetes API Server6 R3 g! r! N4 b4 a$ P6 V
Documentation=https://github.com/GoogleCloudPlatform/kubernetes# v8 s, ^& j4 X# U( k
After=network.target
# ~ i% `, x0 p! ~% V( D4 o4 }( ^7 b" d
[Service]: T6 C" x ]! ^9 T: C! s
ExecStart=/approot1/k8s/bin/kube-apiserver \9 t; P9 }% r9 c1 X3 N
--allow-privileged=true \
* o, w) }$ K2 O- e1 y8 C3 P --anonymous-auth=false \
$ f# u( e+ Q# r7 p3 q --api-audiences=api,istio-ca \
. q8 m! o% e3 F" M& D5 G5 L' o/ Q --authorization-mode=Node,RBAC \ B2 R& ?* e% y- k9 B
--bind-address=192.168.91.19 \4 j4 n' n, n2 v9 y- t' I8 G8 U0 @
--client-ca-file=/etc/kubernetes/ssl/ca.pem \
' e. t1 X* p9 f --endpoint-reconciler-type=lease \
, I/ X! [9 Z3 c% ]) J --etcd-cafile=/etc/kubernetes/ssl/ca.pem \" X1 E3 i1 B6 Y) d j0 E
--etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem \
U, V" W& c6 I# Z. R --etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem \" t, b0 K8 g& N* I' }! ^3 X/ b$ |% |
--etcd-servers=https://192.168.91.19:2379 \
" G/ V! u" B9 L* E- N) t --kubelet-certificate-authority=/etc/kubernetes/ssl/ca.pem \6 o6 j/ Z' \$ X/ V1 M: e4 B0 G+ ?
--kubelet-client-certificate=/etc/kubernetes/ssl/kubernetes.pem \- Y E& h5 x H, i
--kubelet-client-key=/etc/kubernetes/ssl/kubernetes-key.pem \
& }1 ~5 N# {4 i6 c --secure-port=6443 \/ j/ c8 [- e: m1 N+ i; ]
--service-account-issuer=https://kubernetes.default.svc \
' x0 r+ E8 n9 w `, J9 E! C3 B: } --service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
/ t- d7 L7 D5 a# e' }! E --service-account-key-file=/etc/kubernetes/ssl/ca.pem \
' |& z+ D- ~- F, k# s --service-cluster-ip-range=10.88.0.0/16 \
6 i/ d4 X2 A' o/ J1 v- ] --service-node-port-range=30000-32767 \' n3 q8 `3 W/ ~& l1 O) B' @4 F0 Q
--tls-cert-file=/etc/kubernetes/ssl/kubernetes.pem \
7 S- [. S: V _5 d4 F L9 | --tls-private-key-file=/etc/kubernetes/ssl/kubernetes-key.pem \
& W& y4 W/ E$ i: l3 a5 | --requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem \+ g& w. G2 S) h/ A; I u6 A8 S( e+ Y
--requestheader-allowed-names= \
3 f# a5 U, k5 g --requestheader-extra-headers-prefix=X-Remote-Extra- \
: L. y4 h# R; U* b/ l* f --requestheader-group-headers=X-Remote-Group \
# [: z9 m B/ {% p --requestheader-username-headers=X-Remote-User \ r s8 i8 C5 ]: K% t+ S
--proxy-client-cert-file=/etc/kubernetes/ssl/metrics-server.pem \. j6 v8 y6 P0 S: ]* W3 L( Y
--proxy-client-key-file=/etc/kubernetes/ssl/metrics-server-key.pem \
1 h$ z+ N5 T {" | --enable-aggregator-routing=true \
$ t& U9 J& b, j8 P2 j --v=2/ Z7 Z: E* d, {& m8 O
Restart=always! E. v/ Z4 N) ~4 w) p& U
RestartSec=5
- ?& x3 H$ \/ i1 }# L& C0 l, n6 dType=notify
1 u) ~1 R( G, ^8 R: O2 dLimitNOFILE=65536/ t* j$ a4 W! A& s) ~/ o
" h- E/ @# z: Q" q+ e! @& @; w! {
[Install]( V' \+ X- I/ w+ v
WantedBy=multi-user.target
; l9 d' m2 ^, h M2 Q: q分发证书以及创建相关路径
6 i8 A l! r y/ Y- U- z- M' ]如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制% E2 A+ D- k! t
: z5 A7 Y. r. Y- I
对应的目录也要确保和自己规划的一致,如果和我的有不同,注意修改,否则服务会启动失败
. r G- I' u9 X9 E4 D- t' V+ K1 h6 x) W7 A0 o! |
for i in 192.168.91.19;do \
/ _- t/ `6 B3 o' }ssh $i "mkdir -p /etc/kubernetes/ssl"; \
6 F) }- B; h: e ussh $i "mkdir -p /approot1/k8s/bin"; \8 I* Q% t# `& F5 d; w8 S/ V
scp /approot1/k8s/tmp/ssl/{ca*.pem,kubernetes*.pem,metrics-server*.pem} $i:/etc/kubernetes/ssl/; \0 ?- h) |2 D& i% z+ Z9 K8 |, ?
scp /approot1/k8s/tmp/service/kube-apiserver.service.$i $i:/etc/systemd/system/kube-apiserver.service; \" [/ T! b8 D W+ {( ~6 x
scp /approot1/k8s/pkg/kubernetes/bin/kube-apiserver $i:/approot1/k8s/bin/; \
9 q& D L. j4 H- p. ]done+ Z: T+ P4 W7 f" w( E! F
启动 apiserver 服务. c" ?8 @/ {( b/ J: i1 W9 G
如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制% _; [) q% B. o# ?3 y
( Q* b- J8 k" j1 {for i in 192.168.91.19;do \
1 y0 r& R( [% p/ z& l+ essh $i "systemctl daemon-reload"; \( U5 P1 q( }$ }0 |) F
ssh $i "systemctl enable kube-apiserver"; \/ `3 q5 \3 ?& c
ssh $i "systemctl restart kube-apiserver --no-block"; \+ X, ?5 E/ l8 q
ssh $i "systemctl is-active kube-apiserver"; \& ~: x9 Q+ {& s* y) O
done- N0 P; a% B9 D
返回 activating 表示 apiserver 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19;do ssh $i "systemctl is-active kube-apiserver";done
! o% N% d6 V' Y* B# F1 ~* h5 R# h& B( `) O/ F: G
返回active表示 apiserver 启动成功 j2 K$ k$ R. M) x r
' M4 E1 O: m, [; `8 G9 N4 [- mcurl -k --cacert /etc/kubernetes/ssl/ca.pem \1 v7 Y9 Y6 V: }2 u
--cert /etc/kubernetes/ssl/kubernetes.pem \( _, C( O+ s7 ~+ P% |4 {; f3 p
--key /etc/kubernetes/ssl/kubernetes-key.pem \
3 [4 P' L% o. @- m ^$ f rhttps://192.168.91.19:6443/api
/ I" N* [8 i) W* v, h" W) |& P正常返回如下信息,说明 apiserver 服务运行正常
# X8 e6 b" X6 U& g2 o
. r( k9 p, M* f/ W' V9 I4 |: O{
1 g5 u0 p( R, C) ~7 k "kind": "APIVersions",3 p" X5 F) s2 J5 v8 x( K
"versions": [) ?" T- J4 C0 N7 S5 D8 `" m) L
"v1"( n1 s% b) Y3 R6 A6 P( n e; M
],# O& ?. v a+ G5 A8 O- M, G# ~9 y
"serverAddressByClientCIDRs": [
7 C3 M1 J5 u1 z* t {
* [2 R( k# w/ C& b8 n "clientCIDR": "0.0.0.0/0",
7 H) [- E( B8 |! B "serverAddress": "192.168.91.19:6443"
5 Z/ L+ Y! T. Y5 ^' {. ~ }
- G3 o9 o+ {% B/ W ]' \- H- V x2 M! |
} A& L9 Y5 q- {. N3 B
查看 k8s 的所有 kind (对象类别)
( D' W* m7 V6 j1 ]2 I$ e+ n& O' ]* q: @( G7 x' k4 k
curl -s -k --cacert /etc/kubernetes/ssl/ca.pem \
$ M* ?4 `/ `4 \% ~% E--cert /etc/kubernetes/ssl/kubernetes.pem \
3 u( e' {0 `0 I) D) [9 A& E--key /etc/kubernetes/ssl/kubernetes-key.pem \/ v) M+ [4 W* J n3 Y% B/ G
https://192.168.91.19:6443/api/v1/ | grep kind | sort -u
% z" h# M' x6 D8 a: s+ Z0 x9 d "kind": "APIResourceList",' q/ r. e8 b: o4 e q6 e5 W7 T
"kind": "Binding",- U( p9 \2 u% M* t
"kind": "ComponentStatus",
5 O# F) Y( u7 [ "kind": "ConfigMap",
- K* c! u" K9 G# v$ c "kind": "Endpoints",
; T. `$ A! H, Q! V) y; M* x! @ "kind": "Event",5 Y: E5 P/ c. ~( s2 X" I! Z) |
"kind": "Eviction",
7 |! a8 ]9 L5 ~+ e "kind": "LimitRange",
5 r: p' a" `: A3 x' P% h "kind": "Namespace",# P, B+ {) R8 k$ }' L
"kind": "Node",' v9 k1 v% M) J5 r& {9 }3 Q) r
"kind": "NodeProxyOptions",2 |' L/ q; S3 L, l6 v3 h4 `
"kind": "PersistentVolume",* g* r! N, z( H; H6 e2 F% a6 k' M
"kind": "PersistentVolumeClaim",
& D; }6 T. G2 y' S "kind": "Pod",
' B( {( H8 b2 R" ~/ o "kind": "PodAttachOptions",
4 I( t8 o8 G& q "kind": "PodExecOptions",
# o7 a# a: K# I" }, ~8 d$ t "kind": "PodPortForwardOptions", {% F6 w5 j' M
"kind": "PodProxyOptions",/ N* j+ I( ^) Y0 X# K/ P% G! ~6 S
"kind": "PodTemplate",6 Q; ]. x1 t5 Q% J; z( u
"kind": "ReplicationController",
- C5 l5 |; O- K& B' H "kind": "ResourceQuota",
& e; k% e* b }- C3 y "kind": "Scale",
5 n7 S: D; N. S% f "kind": "Secret",
& E- n; N+ Y8 Y" n& a4 E% s "kind": "Service",
- t$ u( n3 Y8 Y3 q2 z7 y- ] "kind": "ServiceAccount",8 ~7 z7 |3 o4 @/ L& C* p
"kind": "ServiceProxyOptions",
6 }3 l$ j! ]1 {$ h! i4 O: y "kind": "TokenRequest",
) m6 Y6 V; N( {! H- A配置 kubectl 管理
! n0 g% v# t0 s# @! o, U创建 admin 证书
" V i+ P! o+ U* S. R% T+ vvim /approot1/k8s/tmp/ssl/admin-csr.json9 B+ j5 u+ p4 M4 }
{
8 f- m( I9 g5 N; N) V9 F& I "CN": "admin",
3 E: D, Z, \. {4 B7 \ "hosts": [/ S; q) v5 l2 a9 s. ?7 P
],# ^9 G0 ^4 z/ s- M, S& U7 L
"key": {
" s( s; I3 P$ j4 `. L6 ~! T "algo": "rsa",
5 }$ r2 \4 \; {& b* r$ t- R( k# R "size": 2048
\7 ~8 o3 H( U },8 V8 u1 j4 M) q: q( G5 w' K
"names": [
( ]: y$ N. ~4 b6 ` {
, a7 \. G3 ^) {& e, ]( U8 @ "C": "CN"," k8 ?4 {5 y4 C Q
"ST": "ShangHai",
5 t- d& w4 G2 R "L": "ShangHai",8 o0 [# Q3 r t8 N8 |* e& |
"O": "system:masters",5 k6 P4 n) D/ S! Y, e# N: U( @
"OU": "System"' s( _' @; [: h0 f7 W5 ]
}
2 `; W& e, c9 f H- l6 a ]. H1 Z2 N, L6 c3 H: P
}" r5 @$ d, G$ z, r' B' I
cd /approot1/k8s/tmp/ssl/
0 ~7 u: ]. z6 h3 y' v* @cfssl gencert -ca=ca.pem \
8 g& P- h+ \$ _, @' k-ca-key=ca-key.pem \1 |2 o# j: l5 s: c$ ~# j
-config=ca-config.json \
; k$ F4 W' b& N5 P( Y1 s-profile=kubernetes admin-csr.json | cfssljson -bare admin
9 v! O: v- t& O( ? L创建 kubeconfig 证书8 Y. O/ Z( W" a% [0 p ]
设置集群参数
6 Z* S* A |3 U, I0 T/ x$ S( d7 S( C% q5 l, j+ D9 z; f
--server 为 apiserver 的访问地址,修改成自己的 ip 地址和 service 文件里面指定的 --secure-port 参数的端口,切记,一定要带上https:// 协议,否则生成的证书,kubectl 命令访问不到 apiserver1 Y7 b9 @$ g G
! w4 l( ]7 N' |& P
cd /approot1/k8s/tmp/ssl/3 ]0 a% {; f* }& S* u* W
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-cluster kubernetes \7 S* P% G0 }& E6 K
--certificate-authority=ca.pem \& p' M$ H+ y) F5 E; t0 P$ w
--embed-certs=true \; z0 G; X# n; Q& b1 i1 t- a
--server=https://192.168.91.19:6443 \
% V2 F& W. O5 o4 p7 d+ E m--kubeconfig=kubectl.kubeconfig
/ P3 J- }8 B0 ~% a3 u& v设置客户端认证参数1 M* Z0 u+ r5 A$ K% d7 X0 y4 S8 `# _
" t+ ?+ `1 W) ?
cd /approot1/k8s/tmp/ssl/
6 w, e, i% Q& s" u/approot1/k8s/pkg/kubernetes/bin/kubectl config set-credentials admin \6 h( \' b9 D5 E$ q6 B u
--client-certificate=admin.pem \, [5 Q4 P9 B) E# q' J
--client-key=admin-key.pem \8 M. Y: f0 v( M
--embed-certs=true \
0 {& ~+ o3 J; ?; [. s--kubeconfig=kubectl.kubeconfig4 {: B6 o( u1 n% G. s/ y
设置上下文参数2 r3 ^' C& `9 _& r$ G& |
- v9 K! F$ v4 }: t1 B
cd /approot1/k8s/tmp/ssl/) ?: T7 i8 s D8 K* c, w1 K: c
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-context kubernetes \8 g% D7 X, C) D$ q8 J K& d' d7 E/ `# s
--cluster=kubernetes \5 s: R0 C$ g# ?* }6 f* J
--user=admin \; B9 h5 l. J2 S: y1 r% P2 e* M
--kubeconfig=kubectl.kubeconfig0 [( x; f( B# V- {
设置默认上下文
; h2 s; u* B9 x! u8 q6 v/ v( S% ~ U1 a
cd /approot1/k8s/tmp/ssl/3 Y9 t5 c+ t. T+ p& ~# B
/approot1/k8s/pkg/kubernetes/bin/kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
$ y2 s, s* `& \+ N% U1 A( `分发 kubeconfig 证书到所有 master 节点
( m0 i) w+ d3 Z, O+ ^( z如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制% x$ y& O* W( f/ w% h. c. \
0 ]1 ?; c) U2 t( I+ y9 yfor i in 192.168.91.19;do \5 C0 o% W% B, W5 T, }
ssh $i "mkdir -p /etc/kubernetes/ssl"; \
2 F! g5 @- c; ] b4 Gssh $i "mkdir -p /approot1/k8s/bin"; \
: Y3 S: ]- C2 S( w& j' U( Gssh $i "mkdir -p $HOME/.kube"; \9 d3 r6 s8 a* Q( i& A5 I
scp /approot1/k8s/pkg/kubernetes/bin/kubectl $i:/approot1/k8s/bin/; \( x' |: D: D E4 f' e; r
ssh $i "echo 'source <(kubectl completion bash)' >> $HOME/.bashrc"
& d' {& A T! Y8 y8 h Rscp /approot1/k8s/tmp/ssl/kubectl.kubeconfig $i:$HOME/.kube/config; \
$ o8 T9 q; s$ x6 t, I, I% ~+ Vdone
$ q) T3 [$ `# s1 a5 J6 E; r部署 controller-manager 组件
( U O: D$ m9 S: B% O6 J+ ]! T创建 controller-manager 证书# }/ E& R4 I1 N; E& Y; d8 I
vim /approot1/k8s/tmp/ssl/kube-controller-manager-csr.json2 P) n5 F6 c, M5 c! `1 [
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴
$ C$ x) n$ n( l: z1 o' E; u% A
! F5 c P7 u6 m! i( L8 D) O) u注意json的格式
- j0 m+ {, O' z. f! F
K+ Z- }! w; w6 p: ^{' g: i* r1 s9 k5 w @) M' F. }
"CN": "system:kube-controller-manager",$ n: S# C+ D3 M0 w" e5 w5 @+ ?2 Q
"key": {
5 {0 y8 m3 @; o& e% k "algo": "rsa",* w2 v9 g6 P d- d) e; A
"size": 20481 \7 t: d# V0 I" W, ~
},
% }6 F3 O, [! D1 D$ `2 E "hosts": [' _1 T G/ J: V& {. A
"127.0.0.1",2 F5 h" U( s& j( m7 `0 ~
"192.168.91.19"
: N- l$ D4 T, k3 G0 b ]," F+ I, W0 @; c& D" t# \2 C( `
"names": [) ?. J3 n6 l3 O8 p6 w6 a
{
- ?3 z/ \" N: `* x' _ "C": "CN"," g) l8 e2 e( P6 f# u6 s
"ST": "ShangHai",: [$ o. L' F+ m0 k+ m! e
"L": "ShangHai",
' E" i( u4 z, ~3 L0 q "O": "system:kube-controller-manager",
4 f) J5 m, z2 e8 o "OU": "System"
* m2 L8 U# @6 ~) d4 h }
# E8 E/ J) ^ u# A, l ]
. j; K3 Q/ }4 |1 U}
6 y9 v. B9 ~ l# ^cd /approot1/k8s/tmp/ssl/8 y9 B& f6 r# c6 Y
cfssl gencert -ca=ca.pem \
5 _1 N o( H* Z-ca-key=ca-key.pem \
$ ~' N7 {! Q/ R4 u% [8 U-config=ca-config.json \, I) v" y7 K5 x/ M6 q O+ `% N
-profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager( X+ A% q7 G; i: ]8 U
创建 kubeconfig 证书. o- W8 M# M) E% C5 G
设置集群参数
, r2 U! a0 W9 U
) O/ A, I1 O( ^# |9 C0 }5 Y' g8 F--server 为 apiserver 的访问地址,修改成自己的 ip 地址和 service 文件里面指定的 --secure-port 参数的端口,切记,一定要带上https:// 协议,否则生成的证书,kubectl 命令访问不到 apiserver" ~& ?7 K+ M/ q, ?
1 \ B- |, O) w( X8 d+ R; H, h' Acd /approot1/k8s/tmp/ssl/! O! u$ ~: m I( B$ o; h9 \8 t
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-cluster kubernetes \
& N* } \9 U7 y" Y; r- ?9 m--certificate-authority=ca.pem \, H; v3 ]# v b* ~1 O9 X0 o3 h
--embed-certs=true \
( A( a E+ z! J# q7 b' Q--server=https://192.168.91.19:6443 \. C* B. r7 s1 d5 Q+ V: K
--kubeconfig=kube-controller-manager.kubeconfig. y# U3 Z3 J& ]- c
设置客户端认证参数
. D8 Y+ v; Z& r8 Z$ S; H
% h" R2 [3 K t/ e) A" ?2 }cd /approot1/k8s/tmp/ssl/$ h6 V0 ]+ r0 Q. g" H3 o
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-credentials system:kube-controller-manager \
# S, j- \: w3 G1 s# {--client-certificate=kube-controller-manager.pem \
2 r+ w. e+ ]. k" B$ o& T--client-key=kube-controller-manager-key.pem \& N1 J; l! l! c8 r" j8 }
--embed-certs=true \
" ~7 @- @9 {) X) ` l; w--kubeconfig=kube-controller-manager.kubeconfig
. [8 B/ f$ G" S; L4 R设置上下文参数
0 X$ @( J' E3 J( x7 K4 y6 X; d( p4 i2 c+ v8 f' K; W
cd /approot1/k8s/tmp/ssl/. u( h; ^' D1 H7 m
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-context system:kube-controller-manager \0 Z$ E; ^8 M2 M! R, |; I4 x9 ?* @
--cluster=kubernetes \ u# p$ C) S4 v: Z
--user=system:kube-controller-manager \* z% S7 _+ r/ R! i- W% |+ C
--kubeconfig=kube-controller-manager.kubeconfig e5 k2 {" U/ m* T Y6 Z- ~
设置默认上下文
. w) R k- S E5 C- L9 K" J+ O" h) T' L1 g9 r
cd /approot1/k8s/tmp/ssl/
; V' f+ M/ p) t5 x1 t1 D/approot1/k8s/pkg/kubernetes/bin/kubectl config \% B, Z/ D7 E1 O2 m3 l2 Y
use-context system:kube-controller-manager \* _; x+ n, }/ M7 U( F: V
--kubeconfig=kube-controller-manager.kubeconfig& E4 B P. O9 D' R6 i
配置 controller-manager 为 systemctl 管理
$ O* f& h t2 Zvim /approot1/k8s/tmp/service/kube-controller-manager.service. N5 J3 D! F3 c8 D; V' b7 \0 z
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴: p6 R8 @! L& r: U1 G
5 _7 U- P3 M ?( s5 F. R
--service-cluster-ip-range 参数的 ip 网段要和 kubernetes-csr.json 里面的 10.88.0.1 是一个网段的
; j7 k, j2 I0 L4 u& ?) E& r7 T! F$ v
--cluster-cidr 为 pod 运行的网段,要和 --service-cluster-ip-range 参数的网段以及现有的网络不一致,避免出现冲突, c+ f: k0 R* }$ O
, F1 e" ?. m6 w R/ s
controller-manager 参数2 T# o- R' J8 y
/ u/ u7 W2 Z- h
[Unit]
% J5 S# b; j$ V' _2 D0 bDescription=Kubernetes Controller Manager& K' k9 |6 x% N2 g
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
4 \' J* v) }( ~2 l2 @* W+ M# b- \( V& i" ?; R+ s# x+ k
[Service]
& ?7 ]+ t+ n4 d4 @3 Q5 _ExecStart=/approot1/k8s/bin/kube-controller-manager \- n# _( ~- u: Z/ b
--bind-address=0.0.0.0 \' r0 l% U5 B! ^( [$ @$ ~+ K
--allocate-node-cidrs=true \$ P8 L! Z* u8 m5 m
--cluster-cidr=172.20.0.0/16 \3 v' t: r. {) C3 g* C
--cluster-name=kubernetes \* m! B, i! h. \: P
--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \4 R) Z2 N4 X3 A e
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \
3 i# K, k9 I/ H+ X6 u --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \
0 e0 X3 W/ d2 R) h9 g, l' o; A --leader-elect=true \
. ]0 H v4 B+ C; M. f, G& w --node-cidr-mask-size=24 \5 {1 `7 d4 A1 L. O @3 Y
--root-ca-file=/etc/kubernetes/ssl/ca.pem \& |0 D& ]. q# C" u3 D9 h
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \
& ^4 O' H7 f) q& G" x --service-cluster-ip-range=10.88.0.0/16 \2 v: o2 ?( h7 H
--use-service-account-credentials=true \
; y- L) s4 D' i: ~* ~ --v=21 g+ b: _ Y5 L, t: Z
Restart=always
4 t3 @) n6 g) a. m: e* mRestartSec=5
b% }3 ]& a! w# X
0 S# F* `- R) T4 r, B6 c[Install]
1 \; A G0 |7 p1 x, {7 f: l \WantedBy=multi-user.target( W& T+ x3 C; f ^: u( t
分发证书以及创建相关路径8 a# T, e) H2 @8 g4 s- u T
如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制
5 h% R) g" H* u- G; D' {
. |* V6 T9 S6 C5 h8 g: \7 E( M对应的目录也要确保和自己规划的一致,如果和我的有不同,注意修改,否则服务会启动失败
. n2 M% a7 p7 r( p! s; Q& ]3 k/ d, a- B# b" r" n8 ]* m
for i in 192.168.91.19;do \' y1 T9 T! Q; v! H7 {
ssh $i "mkdir -p /etc/kubernetes/ssl"; \0 c7 C% _2 R0 p/ o
ssh $i "mkdir -p /approot1/k8s/bin"; \
G; \7 Q( _$ ]) `* i- Cscp /approot1/k8s/tmp/ssl/kube-controller-manager.kubeconfig $i:/etc/kubernetes/; \8 O& ^9 B, F8 g8 ^
scp /approot1/k8s/tmp/ssl/ca*.pem $i:/etc/kubernetes/ssl/; \
$ F' x$ I9 [! q# Mscp /approot1/k8s/tmp/service/kube-controller-manager.service $i:/etc/systemd/system/; \8 T/ s$ i6 J5 C+ t# K3 n
scp /approot1/k8s/pkg/kubernetes/bin/kube-controller-manager $i:/approot1/k8s/bin/; \
5 x. S; j& q' m4 w3 K, @done
9 S; f/ I- C6 K! h2 h启动 controller-manager 服务
% Q/ s X" s% ~- Z! B" |# Q( R如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制9 O* z6 d- m/ [7 I
# g$ \$ k+ V* e2 J
for i in 192.168.91.19;do \8 w8 H* B9 k; ?5 g6 I c$ m
ssh $i "systemctl daemon-reload"; \
9 [ Y$ k! `/ H1 }* {; mssh $i "systemctl enable kube-controller-manager"; \8 r6 {( J! x5 J& V
ssh $i "systemctl restart kube-controller-manager --no-block"; \1 q' d& f5 q$ M$ g+ i2 |+ q% c0 O
ssh $i "systemctl is-active kube-controller-manager"; \) F/ Z5 t6 |4 D0 W$ w7 G
done! f: B/ l7 {) W( `
返回 activating 表示 controller-manager 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19;do ssh $i "systemctl is-active kube-controller-manager";done
/ `' T8 R6 B% l7 V1 ?
$ B. q/ ?7 f. z5 Z返回active表示 controller-manager 启动成功3 e* ?& _; c* @, k1 u& ^# d. Q3 {
1 i3 ]: \7 t& N( [
部署 scheduler 组件
1 Y w) G" F# L8 `+ O5 Q& t创建 scheduler 证书
$ F4 i2 j0 |. S t O7 ]3 y5 s3 |vim /approot1/k8s/tmp/ssl/kube-scheduler-csr.json. C1 y9 T7 y( T/ }
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴8 _5 P9 H; }4 |
4 n8 i3 B! C7 e3 r9 G注意json的格式
, V3 d9 x7 @2 Q' Y% g+ x6 ?$ ], ]3 x: ^
{1 M P: M! y0 p% l- s' M r# g
"CN": "system:kube-scheduler", N) x9 |1 h5 Q" x, k: x1 X1 d
"key": {6 v, Y( J1 p$ M" \" u* F4 A
"algo": "rsa",
6 p! z& j8 D! l) O8 j: M' ? "size": 2048
* P0 T3 _5 [0 s3 U h },
9 f5 q5 W! e: A9 `& O "hosts": [: f( F0 U8 z, T! q
"127.0.0.1",
! G( q; q" a: @7 ~/ B "192.168.91.19", I" N1 Z/ b# S0 g* T4 t% ]8 ~
],
4 @% M- r5 d: g3 U "names": [% i% F6 y* k: F7 w4 y. Y
{1 ~: h, T0 R& Z
"C": "CN",
: u7 x5 F, K$ L" R; o "ST": "ShangHai",
. p) Y: b! I( \! l6 \0 ^ Q "L": "ShangHai",
2 Y' O$ p2 P$ ?% |+ O "O": "system:kube-scheduler",
& V4 @6 o; M. H2 i "OU": "System"
( e/ @( c" H' B. L- N2 s3 Z( r; G8 @3 } }
6 K7 @6 Q" G' `7 o ]
* `3 {: {) y2 ~, u" D9 b" ?0 m}
- M* B- q4 k; V9 [: N: gcd /approot1/k8s/tmp/ssl/
. I, z4 m* c: u9 ^' u& X) ncfssl gencert -ca=ca.pem \" B3 m. E2 y" O) M3 w6 S5 w
-ca-key=ca-key.pem \
" P- n& S, S* C% E2 B-config=ca-config.json \
+ V2 |2 s& B7 v. m-profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
" b6 p- J# l# m. P创建 kubeconfig 证书! |3 q) g2 z8 c: a3 l+ u% }
设置集群参数
" A" ~! i4 N3 w8 u: f/ v r5 Q* d* g0 S# S
--server 为 apiserver 的访问地址,修改成自己的 ip 地址和 service 文件里面指定的 --secure-port 参数的端口,切记,一定要带上https:// 协议,否则生成的证书,kubectl 命令访问不到 apiserver6 P, z$ V. }2 A! s1 t3 p& `7 z5 M# k
" r ~' M+ M$ xcd /approot1/k8s/tmp/ssl/
* ^3 g& T" Z* v% z% o/approot1/k8s/pkg/kubernetes/bin/kubectl config set-cluster kubernetes \( E# c% z9 h: w) B. R7 I
--certificate-authority=ca.pem \
% c3 \4 l ]& ?3 ~--embed-certs=true \8 _% T& h- s0 |8 S7 R3 Q
--server=https://192.168.91.19:6443 \
% t2 ^8 {# S& s1 @+ ^--kubeconfig=kube-scheduler.kubeconfig2 y) o- j" r7 s$ F" r
设置客户端认证参数. v1 S. o2 L x
7 P! n- I! Z/ L) pcd /approot1/k8s/tmp/ssl/. u5 d' ]% C6 F
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-credentials system:kube-scheduler \7 k: `+ K8 r/ M; h
--client-certificate=kube-scheduler.pem \
# q( s& J8 v1 O--client-key=kube-scheduler-key.pem \
! Y* A& h. y' u# n$ ~--embed-certs=true \
# E3 Z: C! k5 D6 \* [$ z R( H--kubeconfig=kube-scheduler.kubeconfig
2 R7 j# |# y% W, r9 n" K设置上下文参数
y% [ e R) `. \9 m
5 i, V$ e7 T! Y6 N1 Rcd /approot1/k8s/tmp/ssl/
1 Z7 W1 w3 w+ I6 P. L- |" v/approot1/k8s/pkg/kubernetes/bin/kubectl config set-context system:kube-scheduler \3 k+ g6 @0 K$ L# B
--cluster=kubernetes \
4 [2 \8 _, I) ]& k0 {% ]' f--user=system:kube-scheduler \3 m6 A: \8 \3 @$ r' d7 C. H. ?
--kubeconfig=kube-scheduler.kubeconfig% j! c+ D, L- S# Y* ]' B& [
设置默认上下文
5 t. t( b& B' l5 h3 E4 Z* Q* U+ k0 v2 T) G5 f
cd /approot1/k8s/tmp/ssl/
~( Z' Q: ]7 U; A0 K5 R, S/approot1/k8s/pkg/kubernetes/bin/kubectl config \: h3 W5 g/ t+ u" g3 ]& v6 _
use-context system:kube-scheduler \
1 M- B2 d% z) M+ {7 V0 B4 t: s--kubeconfig=kube-scheduler.kubeconfig' x0 e; p9 O% }3 g/ O6 A$ H9 H
配置 scheduler 为 systemctl 管理
( b# \, R# j7 [& avim /approot1/k8s/tmp/service/kube-scheduler.service
; i* @! `$ U6 |; u* ^' Uscheduler 参数# O+ p6 k( B! Y# X" X+ o
1 q' q4 l" y9 | n1 b9 r[Unit]
, q) B$ V' [5 j$ Z: jDescription=Kubernetes Scheduler
6 Q* T: o$ A. n _# wDocumentation=https://github.com/GoogleCloudPlatform/kubernetes/ s* d, L3 c! M3 G8 x4 j
5 i. K$ Y- Y: }[Service]1 g! Y: ^& x8 f
ExecStart=/approot1/k8s/bin/kube-scheduler \" s, q6 W, r9 r9 @2 L& v
--authentication-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
/ h! I5 c! w. f- A0 l: d- P; M P --authorization-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
3 W! }# R2 D" G# p$ B' k --bind-address=0.0.0.0 \$ i. v4 I$ ^5 G/ j
--kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \
e: d: y3 B4 E* [ --leader-elect=true \
/ D1 Q4 U0 j1 t" U- j --v=2* Y F! f, u+ P6 Z/ `1 o. p
Restart=always
& \3 E: L! t4 T/ ]RestartSec=5
, Y2 f" q1 R: Q% P. j% U
; `& I! s) D( `1 @. R/ t& w[Install]
# j; c/ \! @6 t( {4 U% E, ?WantedBy=multi-user.target. ]. b6 U5 D' H* C! K
分发证书以及创建相关路径+ [* K* C0 W5 g: k' x4 n7 @ q7 X
如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制( U. t' }. N( c: J2 X6 L8 e
% ]! Z) U0 d f1 C
对应的目录也要确保和自己规划的一致,如果和我的有不同,注意修改,否则服务会启动失败9 b& b) N/ D6 d# s0 y* H9 x
* O' m ^. a) }
for i in 192.168.91.19;do \0 C/ d3 n1 C; O1 v* |
ssh $i "mkdir -p /etc/kubernetes/ssl"; \
1 b' i- W# a s3 p# _ssh $i "mkdir -p /approot1/k8s/bin"; \
8 f' v! e: F( {+ kscp /approot1/k8s/tmp/ssl/{ca*.pem,kube-scheduler.kubeconfig} $i:/etc/kubernetes/; \
# M0 [$ p8 a" a+ F2 f' a- F& rscp /approot1/k8s/tmp/service/kube-scheduler.service $i:/etc/systemd/system/; \; D1 j2 S/ C3 C3 ~# R/ B4 @
scp /approot1/k8s/pkg/kubernetes/bin/kube-scheduler $i:/approot1/k8s/bin/; \4 X) x& }' n+ p; w: i
done
. ?# l, z3 G x% G3 b: }启动 scheduler 服务, j* p& v. J, f
如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制+ |0 L& F8 j+ L
" o/ `# C! n! ?+ ]! o
for i in 192.168.91.19;do \4 K9 `& P; K8 [
ssh $i "systemctl daemon-reload"; \2 d0 A# M, t) ^% o9 G1 D
ssh $i "systemctl enable kube-scheduler"; \+ h: S' T8 s4 R6 j* R
ssh $i "systemctl restart kube-scheduler --no-block"; \
& u( [. S' P: G/ O( T' Ussh $i "systemctl is-active kube-scheduler"; \
, o/ c, W; g8 l8 b Z9 S; s& l% w9 bdone
/ J0 P; E7 b `返回 activating 表示 scheduler 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19;do ssh $i "systemctl is-active kube-scheduler";done* a$ P1 E) g$ `; Z# V* _) T
: u* ^! P" f3 j4 C) N. }6 {
返回active表示 scheduler 启动成功" c. C- b; {; D
5 x) Q) a7 Q* M部署 work 节点
) l) `- Y! |' f1 \* b' s部署 containerd 组件4 S8 a8 m% S2 U: i1 M. G
下载二进制文件
9 l& L$ P% S1 s/ bgithub 下载 containerd 的时候,记得选择cri-containerd-cni 开头的文件,这个包里面包含了 containerd 以及 crictl 管理工具和 cni 网络插件,包括 systemd service 文件、config.toml 、 crictl.yaml 以及 cni 配置文件都是配置好的,简单修改一下就可以使用了( W- \/ ]: C5 i1 P3 }! }2 c* O, w
& m9 i. B0 d9 s0 q b虽然 cri-containerd-cni 也有 runc ,但是缺少依赖,所以还是要去 runc github 重新下载一个' ?/ Q* P+ D) Z- N" U2 \
* t8 K- h- M. X* vwget -O /approot1/k8s/pkg/containerd.tar.gz \! \! |% K* L' j! ]& V$ e* `
https://github.com/containerd/co ... -linux-amd64.tar.gz3 ~6 h" \/ o4 \
wget -O /approot1/k8s/pkg/runc https://github.com/opencontainer ... d/v1.0.3/runc.amd64
' b0 a* X) _ A3 s8 K, |mkdir /approot1/k8s/pkg/containerd; N6 `% ~5 h. R W6 a
cd /approot1/k8s/pkg/
" `( B, H) }6 L4 ?for i in $(ls *containerd*.tar.gz);do tar xvf $i -C /approot1/k8s/pkg/containerd && rm -f $i;done, N6 A$ s0 O6 M* J% l3 n' |3 c
chmod +x /approot1/k8s/pkg/runc) d& D8 `, r7 @7 d, L# F
mv /approot1/k8s/pkg/containerd/usr/local/bin/{containerd,containerd-shim*,crictl,ctr} /approot1/k8s/pkg/containerd/
$ {1 S" ]2 K N7 N+ T! V8 b1 omv /approot1/k8s/pkg/containerd/opt/cni/bin/{bridge,flannel,host-local,loopback,portmap} /approot1/k8s/pkg/containerd/5 k" a* ?7 ~% y; d( }5 K+ ?
rm -rf /approot1/k8s/pkg/containerd/{etc,opt,usr}. N2 k) _# _" a: U3 I5 H$ ]
配置 containerd 为 systemctl 管理0 a) B; U1 p- Q- l+ ]# h! u
vim /approot1/k8s/tmp/service/containerd.service
. d( L: M* O/ Y注意二进制文件存放路径
% q2 T& U0 \: S) K7 x: r3 `
# b* ^1 w2 n2 I r( I d4 z如果 runc 二进制文件不在 /usr/bin/ 目录下,需要有 Environment 参数,指定 runc 二进制文件的路径给 PATH ,否则当 k8s 启动 pod 的时候会报错 exec: "runc": executable file not found in $PATH: unknown
0 }4 X" f) K) ~
8 |' `* _* U( s; E4 K- k8 c[Unit]
7 Q' _- y/ ~, h) R+ x8 `Description=containerd container runtime4 K" s8 `& _4 C, D
Documentation=https://containerd.io
|' z. Q1 q3 ~ P3 J; Y4 [% sAfter=network.target, w# b9 q! [ K, |" N
) ?. V) u/ @, z- Q7 H, B4 `! C2 e& @. M
[Service]
2 f$ D1 J" s' ^+ Z5 _5 W( k( F6 qEnvironment="PATH=$PATH:/approot1/k8s/bin"( G* Z7 O: ~) y9 S# k
ExecStartPre=-/sbin/modprobe overlay
) C% ]& V. {8 g. x. UExecStart=/approot1/k8s/bin/containerd9 C1 u6 l6 v( }, @) w6 f' ^4 V1 J! e
Restart=always; ^" X; @ g& Z7 N/ w
RestartSec=5, ~. G1 [% t2 ]7 K6 G7 I
Delegate=yes
- O% y4 ~! o3 JKillMode=process
: s; \5 n: L7 N/ oOOMScoreAdjust=-999
' [, u3 q0 Y; S u& b* dLimitNOFILE=1048576, r. X$ p$ Q, R4 u! j) T- Q
# Having non-zero Limit*s causes performance problems due to accounting overhead
' n6 S) e9 E) @* q; n5 E( w0 S3 \# in the kernel. We recommend using cgroups to do container-local accounting." s5 V p+ T, ?. y: Q6 p
LimitNPROC=infinity, J1 a" M4 k% X4 q1 o$ G
LimitCORE=infinity1 m. l7 j; v7 \6 w$ r
. I4 M( C2 m, W( s1 z9 R+ b
[Install]
: B, G! }, L3 f% ZWantedBy=multi-user.target
$ U+ u' K7 v3 L( e9 R配置 containerd 配置文件+ }: ^: j" r1 o5 y2 k: u
vim /approot1/k8s/tmp/service/config.toml
" L4 {* y& o) @8 G4 a# ], Y5 Nroot 容器存储路径,修改成磁盘空间充足的路径
0 C5 u6 ^5 h% f
: c* O* V! @/ hbin_dir containerd 服务以及 cni 插件存储路径" Y1 o$ T3 R' |3 ?/ S, ~" u/ a$ `
& P5 |$ y0 `0 N9 R L
sandbox_image pause 镜像名称以及镜像tag0 m3 Z0 r. k% t s, D& x
" ]9 {6 N# }3 s& L: F
disabled_plugins = []! H* B7 U7 a4 Q$ {
imports = []
( T* ?2 d) r9 r# t- a* hoom_score = 0
5 Q$ p7 R1 R# U0 uplugin_dir = ""
' i$ D) E7 ^0 o; i) L2 Krequired_plugins = []8 Y, y2 y/ s/ H X% q9 h" f( ?
root = "/approot1/data/containerd"
3 \, a+ T" i+ _1 D+ Tstate = "/run/containerd" a" i0 _4 c" S+ h* V' U
version = 2
8 p# F3 O+ |1 l) `2 V; K. U
) d, S5 W3 {* B8 C5 x2 ^; y$ H6 e[cgroup]
* E( I l( Z0 f+ u path = ""
$ B9 E: O4 h! \+ {8 A
. G+ F8 a$ H% x[debug]1 n9 z1 k9 p) `3 M7 H
address = ""8 w1 f2 s- i2 z0 u. v- {
format = ""7 \4 p! K+ D+ o
gid = 05 W7 |; U) M$ @8 R+ C S/ D* U- ^
level = ""* F: x3 W; N( Y2 Z: Q
uid = 0# L t6 c3 }# \* { K" y. N) }2 \
. }: Y) D6 J" m9 R+ |[grpc]
- `) {6 h; t5 b' X7 A& h5 w2 Z address = "/run/containerd/containerd.sock"$ y& s, d* U" b
gid = 0/ G) x, V$ G& v; { X! W8 I
max_recv_message_size = 16777216
+ M6 `6 F: R; E2 c. s max_send_message_size = 16777216
) k" a2 x4 b; m tcp_address = ""9 P- `! |/ j% A+ {8 o2 A; a2 @
tcp_tls_cert = ""
9 w8 Z# P. E! l4 c1 m6 V' ^ tcp_tls_key = ""
: Z( U& j7 W" m3 f: ?# Z; U7 k$ P" ]' G uid = 0
. f0 h/ Z* ]% Q2 }7 ` e" O# a i5 O1 g
[metrics]
7 R# I# B1 E4 p ?! Y! L3 s$ K address = ""' t4 n* P# c( h: I4 T: w; h! T
grpc_histogram = false
y1 \- O' R5 M. B9 ?7 ?8 m7 e3 c+ J
[plugins]! e: y9 |: M8 q, V* i
! j9 Q" C6 Z' A& H! j3 C% I
[plugins."io.containerd.gc.v1.scheduler"]( F0 e5 r% N6 [6 n" h. n% F- s/ c" S
deletion_threshold = 0( v2 t% Q/ M0 E/ k* Z% s
mutation_threshold = 100
% Y# O/ J' |! z pause_threshold = 0.02. H' E+ l \. t7 Y. C
schedule_delay = "0s"
( k0 I' q- Z& J9 b9 n- } startup_delay = "100ms"
1 L+ |$ |9 C B7 ^8 c
9 s8 k4 E; k. O/ G$ }' z [plugins."io.containerd.grpc.v1.cri"]
8 Z- l& R5 a# y9 t9 r disable_apparmor = false$ H& E$ c4 c0 b
disable_cgroup = false
' O6 U; e2 b1 h: Z2 |) ] disable_hugetlb_controller = true# m% x) s/ N; D4 S9 w! _! G4 |
disable_proc_mount = false
; L; y" i2 U" }) a& x( C8 u4 R& H disable_tcp_service = true
# ^; \ M# d0 B* ]* L6 x& h enable_selinux = false) a2 d W- p( T3 @ Y5 p% p+ m1 t8 T
enable_tls_streaming = false
% c7 A9 v8 O m ignore_image_defined_volumes = false
/ U. F$ i( _+ J3 \4 `. E: e max_concurrent_downloads = 3$ J# I; s: G g8 w& F1 ~* |& n" }
max_container_log_line_size = 16384* z6 e: A! m/ `$ B( y: V& k
netns_mounts_under_state_dir = false( q: T4 q4 k* Z! R2 s! e7 @: ?
restrict_oom_score_adj = false+ i$ q0 ?% @6 X) _
sandbox_image = "k8s.gcr.io/pause:3.6"
, N0 F4 c4 f7 _+ y3 ~ selinux_category_range = 10241 q# A* W( g4 b/ G1 Z+ u
stats_collect_period = 102 Y9 w, M0 V2 m# r6 l5 \7 k
stream_idle_timeout = "4h0m0s"
{! c) b8 i5 {. z$ q7 I- d stream_server_address = "127.0.0.1"# m6 q @3 E: V9 X1 o0 H& g
stream_server_port = "0"' w4 N3 ]3 o5 s% P4 j8 G
systemd_cgroup = false
7 @* x d8 o1 L9 \8 f0 A tolerate_missing_hugetlb_controller = true& l/ W& p! b4 F) ^% m
unset_seccomp_profile = "") M) [ V6 Q* h
# @' Y* ^; a7 X2 A. p6 _ [plugins."io.containerd.grpc.v1.cri".cni]
) O9 W& ]6 A) X. |7 w7 C bin_dir = "/approot1/k8s/bin"6 p( y, O# F9 {( p3 t) q. ^' f
conf_dir = "/etc/cni/net.d"* q4 {1 T' `! {, l
conf_template = "/etc/cni/net.d/cni-default.conf", k% K5 M$ i. L- a" m, t
max_conf_num = 1
/ U( a% g( `$ l( p& i7 o0 O' |) V% n0 @9 E! S; ?5 u
[plugins."io.containerd.grpc.v1.cri".containerd]; J9 _5 U6 D0 `
default_runtime_name = "runc"
0 L- \# Z) B5 j& w- e disable_snapshot_annotations = true7 H, Z4 o: q( g5 R$ m* |, a' y; {; }
discard_unpacked_layers = false
) x/ t5 B- f. I3 d/ ?. \1 @3 z no_pivot = false% l# h4 b4 P+ m/ t
snapshotter = "overlayfs"
! s5 m) L R) L( c- B0 v4 {3 |6 ]8 t5 G1 T' d5 N- w/ V
[plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]# z& i( i2 q6 x% T
base_runtime_spec = ""0 Q) y! z0 N- ? K; X% r v
container_annotations = []
& Y% V0 D) ?% X Q pod_annotations = []% p+ ]% i l7 j( {* B7 `
privileged_without_host_devices = false/ s9 N7 N) r9 Y7 [
runtime_engine = ""
) b. e3 O8 X( H- x runtime_root = ""0 Z3 ~- i L% P3 t
runtime_type = ""
+ n3 l( W: \3 w. X$ S$ v
" A% @8 R9 o: M i& Y [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options]; U, B% Q+ a m$ E' I1 G) @5 e
2 y4 |6 l: D% L, T4 C9 R3 ~
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
3 t0 L( g- [/ _) t7 ~) Z; |& ?* k
" k# _; Z% I8 ?3 j" c, r [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
* ]$ j3 @; x2 Q) ?; Y base_runtime_spec = ""
; x6 A! m6 O8 J% `; M8 @ container_annotations = []
( O5 l/ V! D/ n- Q g- X8 X pod_annotations = []% F: L3 k2 x& P9 z, _+ B4 E
privileged_without_host_devices = false! @. X8 j# Y7 f4 }* f# _
runtime_engine = ""! g3 p7 K, K$ T0 K2 D8 N8 o
runtime_root = ""
4 Y' a1 g% Q3 f- v runtime_type = "io.containerd.runc.v2"% T% b h4 w9 K9 y& S2 w% o! t) V: W
3 Y: P! o: s" F5 w; K: E1 M# B& X! J4 k7 S
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]: V& [7 T8 I9 b9 {" Y
BinaryName = ""9 m( _: j7 d6 c* d. v5 o& I
CriuImagePath = ""
8 Y2 j `/ ~. f, W" K# ? CriuPath = ""; p( {/ T0 k S/ K
CriuWorkPath = ""
3 ?3 p1 Y$ R% Y" l( c IoGid = 0* L3 A' Y9 i5 I4 K1 ~
IoUid = 0
, g* z( V' B1 U7 U* }8 ~ NoNewKeyring = false
3 r6 ~ z/ p( T, q NoPivotRoot = false( H7 T& p5 Q4 l
Root = ""
9 P/ y6 \1 I8 q: W/ d ShimCgroup = ""7 N8 F( i M# o4 E$ P9 `6 G
SystemdCgroup = true
6 O% Y9 n9 |0 H8 a& r: z
; o% M0 D: e7 g- ~( B9 ? [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]4 _. N. F6 E" ^1 `# Y3 Z
base_runtime_spec = "". O6 \, q4 \& T: X. i5 S A+ b
container_annotations = []
8 J. o; H; a& h& @$ z( R0 `5 H; q pod_annotations = [] w2 x* [+ Y/ S" H/ G% g$ s X
privileged_without_host_devices = false
6 x3 W: u/ C/ G; _1 X6 u4 `( ~ runtime_engine = "", D( T- A& n& [( @" Y' ?2 i: e& `2 S
runtime_root = ""9 }. j. H. ^4 g5 u
runtime_type = ""9 z9 H$ s+ p2 F+ T; Z0 v! s9 x
e6 _7 k2 H: [; N( p0 E
[plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options]! b- J/ }$ i* ~2 U/ X2 E1 ?6 U
) W4 U: I$ ?! v# g$ ~6 |1 r, k [plugins."io.containerd.grpc.v1.cri".image_decryption]7 i/ ~3 g" [& a" G* K
key_model = "node"
5 q/ Q F- M* k
9 W* l. t4 }. O2 D d/ G [plugins."io.containerd.grpc.v1.cri".registry]
5 y1 z; v7 Q. {$ h8 L4 y config_path = ""
/ j# x1 Q% W0 _
5 k q B, g- `2 N* w' ] [plugins."io.containerd.grpc.v1.cri".registry.auths]) {7 k: a& p; F* P
; \' N: ~1 t" U
[plugins."io.containerd.grpc.v1.cri".registry.configs]
: q- N9 ^5 ^; W7 Y" Z/ ?7 x- A4 u4 c: [3 X6 A4 A+ Z, m+ E! z
[plugins."io.containerd.grpc.v1.cri".registry.headers]7 U# W8 F. o5 G, I
- O* l; t4 o* H( I- W1 \( Z% k0 ?
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
R* E( q2 e9 X [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
& c$ W T" [+ K7 V; i. T endpoint = ["https://docker.mirrors.ustc.edu.cn", "http://hub-mirror.c.163.com"]
5 |3 g7 A4 M$ H [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
$ }3 e2 h4 K- N% | endpoint = ["https://gcr.mirrors.ustc.edu.cn"]' i. x i$ Z, i" b3 j
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]+ x2 u$ b, ~! e$ b- K3 U
endpoint = ["https://gcr.mirrors.ustc.edu.cn/google-containers/"]
" F0 |5 S' A, W7 ^ [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]3 L8 N) d# o4 H9 q5 H3 ~7 ~( A, S
endpoint = ["https://quay.mirrors.ustc.edu.cn"]
( l/ \, r9 n1 }/ Q
. z- t( M: F. t8 F! C# ` I1 [ [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
- A4 _: o6 `4 d- J9 i tls_cert_file = ""4 X2 q& n7 h5 J, N6 g2 D
tls_key_file = ""6 A* J+ r9 ^, Q
* j0 R; V) O; L! x" C
[plugins."io.containerd.internal.v1.opt"]
& Q: ^, C+ H/ p8 I8 m0 T. ] path = "/opt/containerd"/ }) V( _ G/ m+ B* t6 H0 P$ R
1 Z! t G9 ` C. k1 e1 J( N
[plugins."io.containerd.internal.v1.restart"]
4 @2 v9 d$ w5 V& Y interval = "10s"- D" c$ o2 y* W4 W0 \5 E
4 u* b: H5 ~- D- A6 O
[plugins."io.containerd.metadata.v1.bolt"]* E; p# f, ?, a3 M) T/ L% |
content_sharing_policy = "shared"3 a6 J: X' D1 O% r# V8 n+ T) d, i
- [/ l7 g9 U, R5 `' r& L [plugins."io.containerd.monitor.v1.cgroups"] O9 J* n# }& I9 ?6 B
no_prometheus = false
+ i3 G% ^ O8 V1 B; T7 G$ [* G/ [# H4 I/ h
[plugins."io.containerd.runtime.v1.linux"], M1 t$ {( r) P6 i4 s. m* }
no_shim = false7 @) n9 ~& \. Y# r2 |. e
runtime = "runc"
) `9 m+ `1 m8 F- l" h4 W: f runtime_root = ""3 [$ _; h7 ^& Z7 B# \; T! L z' G
shim = "containerd-shim"
( B( n8 k6 U8 D) j" h3 P shim_debug = false
" u1 ]+ a: T8 ^) ~: \
# d, g$ }* q9 k# o! [6 e" @4 x" t [plugins."io.containerd.runtime.v2.task"]# z5 ?/ |9 s! Y+ A7 s1 k
platforms = ["linux/amd64"]
; B+ K" Q U8 D/ b3 m- o% c6 ]' ?; X; e! ]9 @4 N
[plugins."io.containerd.service.v1.diff-service"]9 m5 Z+ v0 \4 r, z% U' U* e. G
default = ["walking"]
- L( O0 m# |6 W
( q: k( v; U3 U* R5 d) u [plugins."io.containerd.snapshotter.v1.aufs"]
; w1 ?$ q: D8 |1 a. V+ Z# J; o root_path = ""9 H7 G1 t0 @( q4 j: z2 d
$ h9 F1 A6 T2 g6 {! L
[plugins."io.containerd.snapshotter.v1.btrfs"]
; p' @( V3 X' K0 o4 ]# _ root_path = ""
' V1 a7 Y" E( O: z( @) `+ R( D
[plugins."io.containerd.snapshotter.v1.devmapper"]
% ~* p- H# X/ T/ s9 O* K async_remove = false" Y; Y- S7 P7 e
base_image_size = ""
X* H1 \( G) v3 c pool_name = ""& t! w& _) W* \& d. [, h2 {
root_path = ""- Y/ H5 {2 G0 l( g7 x8 Y& n- ^8 h
* I! D1 C8 o" S# j [plugins."io.containerd.snapshotter.v1.native"], o f. \4 Q+ S, S$ J* a; t6 {
root_path = ""
6 d* H7 T4 K1 [) V2 [& z2 D8 c {4 v1 `8 P2 d2 o, Z. }* }
[plugins."io.containerd.snapshotter.v1.overlayfs"]
3 g0 s% ?. L+ H j2 D" ~: I2 J root_path = ""
* F, o' m+ V2 _2 y% x: [. }6 |; G3 p; I
[plugins."io.containerd.snapshotter.v1.zfs"]
$ R& j4 p% h) z' U2 W1 I" `# V0 q+ ] root_path = ""1 i! ?1 D3 L" @
! C" z/ i: V6 V: X8 O# W- Y
[proxy_plugins]
1 R7 t. T+ _5 {0 w) ~9 x" Q9 h) E0 k" t: m
[stream_processors]
) {' G+ B% O/ U, ^8 w8 V' k, F1 p5 ]1 m
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
) b8 ~9 O c* v, V: d* | e accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]5 [5 L0 |/ `/ x7 ?9 A
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]) `$ Z2 ^: W4 Q
env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]* `% |% E3 C* _7 L: \9 n$ G' r
path = "ctd-decoder") U ]1 |+ M* K N. b. H9 B0 h
returns = "application/vnd.oci.image.layer.v1.tar"
! m$ c$ c1 w. N6 ~: ?( u4 }
B [- c4 T5 I5 G [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
7 S7 B6 r3 V* I7 Y! [$ | accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]$ o" l W6 [5 Z
args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"]
9 B+ s( m6 _2 W$ ~ env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"]
( c+ p# F- i8 W& Q' a path = "ctd-decoder"
2 X1 q) G" X. x- j" P returns = "application/vnd.oci.image.layer.v1.tar+gzip"8 R/ N# D0 o2 N9 l7 G
/ X; b8 x: d8 W/ I _9 B[timeouts]: b5 E1 ]2 j# C* q
"io.containerd.timeout.shim.cleanup" = "5s"
* {6 o# G4 D' t+ x8 }: Q "io.containerd.timeout.shim.load" = "5s"
8 I5 V% h4 f- `# V5 K7 j" u "io.containerd.timeout.shim.shutdown" = "3s"! B) s9 N# \6 y+ Z) |6 G6 h3 w
"io.containerd.timeout.task.state" = "2s"* Q2 H. j4 ]) ^2 F/ g
& @% g6 a" x% F j5 n
[ttrpc] E4 o2 m& x+ w6 m
address = ""' n" |& q+ t0 i4 ]9 _: z
gid = 0
8 L1 g4 w+ H! W6 N: p+ s uid = 0* @% F3 E0 F( [6 O% Z0 E% g
配置 crictl 管理工具
: h9 L$ i2 M0 N& g+ A. c% jvim /approot1/k8s/tmp/service/crictl.yaml
" G, U+ ~, K$ {1 ^4 ^( \2 }runtime-endpoint: unix:///run/containerd/containerd.sock% {% f, ?' N8 Q; F1 b a
配置 cni 网络插件
* d# ]; |* ?7 w5 c/ lvim /approot1/k8s/tmp/service/cni-default.conf y' x6 l5 y" c3 M+ |( z
subnet 参数要和 controller-manager 的 --cluster-cidr 参数一致
# T) z; w7 x. a7 ?- X( j; M: H1 B" Q9 m( t: |; g4 ?& S8 C
{
* V/ I, c0 A; C6 A( f. k "name": "mynet",$ \; ~8 V3 T/ u
"cniVersion": "0.3.1",; _5 D! F7 c2 @5 E' u; \8 g1 t" C
"type": "bridge",$ K2 a& L: k% m2 `. A2 J8 P( Z
"bridge": "mynet0",$ n* g- i- [2 V
"isDefaultGateway": true,
; G0 D& A$ |, a" E. }# j1 r8 v "ipMasq": true,
' ]; ~# j6 \! ^7 o "hairpinMode": true,
1 u5 \2 S/ L1 v# W5 i' h- V "ipam": {
* E7 f4 Q/ e0 L3 a: ^ "type": "host-local",
; W5 Q) ]7 l, [& @4 k4 C+ {; g "subnet": "172.20.0.0/16"* f0 z$ Z3 a; A5 J5 j
}
; v* d7 V( o4 ]7 @}
, z8 N, b" l0 n分发配置文件以及创建相关路径$ D: q; c5 w* Y* Z/ o
for i in 192.168.91.19 192.168.91.20;do \( d/ g5 v7 M" @8 P( Y
ssh $i "mkdir -p /etc/containerd"; \
- K% J. j" t' h' Wssh $i "mkdir -p /approot1/k8s/bin"; \
" f1 s, b, _/ L T. |" Lssh $i "mkdir -p /etc/cni/net.d"; \
) C0 E7 g* `( n4 A1 O6 H! s: z8 }! zscp /approot1/k8s/tmp/service/containerd.service $i:/etc/systemd/system/; \
3 b$ O8 A) T+ O* {scp /approot1/k8s/tmp/service/config.toml $i:/etc/containerd/; \
, H6 X# z) V# j; M7 qscp /approot1/k8s/tmp/service/cni-default.conf $i:/etc/cni/net.d/; \$ h$ A# k! z3 P z+ z( N$ t Q0 J* f
scp /approot1/k8s/tmp/service/crictl.yaml $i:/etc/; \% W% y3 o3 B, D! k0 j2 b6 P. }
scp /approot1/k8s/pkg/containerd/* $i:/approot1/k8s/bin/; \
: X! a: M; L3 z. Q) W0 Escp /approot1/k8s/pkg/runc $i:/approot1/k8s/bin/; \
! F2 H i0 l, o& I. ?0 Ldone# h1 P0 `! P4 ~% A& h
启动 containerd 服务
/ |1 r/ D! G' `+ |9 w9 `' `for i in 192.168.91.19 192.168.91.20;do \
h" h6 Y, l, J8 \. y% K7 g! j$ J( b6 Assh $i "systemctl daemon-reload"; \
1 H. N/ v3 h% L: assh $i "systemctl enable containerd"; \
6 Z, }+ P' m& Issh $i "systemctl restart containerd --no-block"; \+ N# e# b% j% T9 b8 y* B5 p- C0 \3 S
ssh $i "systemctl is-active containerd"; \7 _6 q' j! x) M( T
done
4 r& x9 ], |% d+ ^+ }6 o5 P% S返回 activating 表示 containerd 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19 192.168.91.20;do ssh $i "systemctl is-active containerd";done
" F; G8 \+ T$ o7 {- ]3 |3 T5 L& s# f
返回active表示 containerd 启动成功
s' ~) E0 B4 y8 ?
5 I0 v8 n+ W! Q* q0 Z+ p* _导入 pause 镜像% J2 S d4 U2 S k: j* h
ctr 导入镜像有一个特殊的地方,如果导入的镜像想要 k8s 可以使用,需要加上 -n k8s.io 参数,而且必须是ctr -n k8s.io image import <xxx.tar> 这样的格式,如果是 ctr image import <xxx.tar> -n k8s.io 就会报错 ctr: flag provided but not defined: -n 这个操作确实有点骚气,不太适应: p+ t' i) A+ w
% h9 g# @4 Q1 V4 ?; z% D如果镜像导入的时候没有加上 -n k8s.io ,启动 pod 的时候 kubelet 会重新去拉取 pause 容器,如果配置的镜像仓库没有这个 tag 的镜像就会报错
% O( O" V# }( h+ a) r P2 G: f# O# I" y4 n; v; u9 q9 b) u+ U' }: g; E
for i in 192.168.91.19 192.168.91.20;do \
i( S. {7 U! Z5 l vscp /approot1/k8s/images/pause-v3.6.tar $i:/tmp// H. S- |. \# w
ssh $i "ctr -n=k8s.io image import /tmp/pause-v3.6.tar && rm -f /tmp/pause-v3.6.tar"; \
* ^6 ?, s3 p4 w3 w/ ^0 @* jdone
2 e; o( y) L5 H2 K1 c+ O7 \# M9 k查看镜像
5 S1 n$ c* n1 b* }0 _' Y
: }9 Y1 m: R2 j- n" A' Tfor i in 192.168.91.19 192.168.91.20;do \3 [$ W9 H: G6 n o; H( @2 Z
ssh $i "ctr -n=k8s.io image list | grep pause"; \3 w: X3 Z5 U. g* e* q# Y
done8 j2 {. L/ ?/ g/ P% d
部署 kubelet 组件2 O& q* P$ U) O' H8 z Y* P) D
创建 kubelet 证书5 c! _ a1 u/ Y! g4 J
vim /approot1/k8s/tmp/ssl/kubelet-csr.json.192.168.91.19' r6 T8 h3 P) X; P0 B3 H
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴,有多少个node节点就创建多少个json文件,json文件内的 ip 也要修改为 work 节点的 ip,别重复了
2 |! O" L6 m! |& @3 [9 t8 B+ _& U8 ~; a9 q' E& f$ p' X
{
0 q* c' D! e/ |+ Z8 i& @, f' o9 F "CN": "system:node:192.168.91.19",
5 \( N3 K" d; J8 O8 ^6 {2 y "key": {
9 S% I7 ]" c$ D% J$ p4 E& _ "algo": "rsa",1 c. z; m) X, K* v! Q4 {; b5 Q
"size": 2048
/ c2 {, M! G# [% Y: v },
# M* s$ E- i4 f1 M" g "hosts": [2 @3 K) O$ i$ i, y q0 a+ y
"127.0.0.1",# _+ D' q4 U4 [) |
"192.168.91.19"* I4 z% {) h( Y& W* B" }
],/ p3 y0 y+ |# q
"names": [
) }# g' B. q* s% n0 C {, c A1 K7 x; q
"C": "CN",
& A6 Y3 K5 D p1 X "ST": "ShangHai",# i4 v3 h# ^% u( l% f
"L": "ShangHai",/ X) A0 }. L3 A* F: Y9 i8 m
"O": "system:nodes",# k+ M3 }3 ~1 l# Y& \8 `, M6 V7 h/ e
"OU": "System"
2 G$ S: W; p) z X, h: F }
7 S& n% U' \! t ]
5 Y Z. @- n* z, n% w3 R! U+ i3 e. h}
6 P2 @: X$ ?9 [- G0 W" u1 |# A6 Ufor i in 192.168.91.19 192.168.91.20;do \8 m, h9 I9 I0 r" R: c/ L
cd /approot1/k8s/tmp/ssl/; \0 s9 A# ^8 f5 N' t( ^: { {* X7 Y6 |
cfssl gencert -ca=ca.pem \% k+ H4 E$ ^$ A d6 Q& M' |
-ca-key=ca-key.pem \) f+ o& y1 Y; W, m; F% _
-config=ca-config.json \
- L& f" s; B: P+ T+ @* K-profile=kubernetes kubelet-csr.json.$i | cfssljson -bare kubelet.$i; \0 @7 U$ s( t* q( S6 W; g& H% x
done* m/ S* l$ D8 S
创建 kubeconfig 证书% s* _% E D1 T6 f
设置集群参数8 z% O! F/ I+ b. Y
& c* u3 k8 O A9 c8 m--server 为 apiserver 的访问地址,修改成自己的 ip 地址和 service 文件里面指定的 --secure-port 参数的端口,切记,一定要带上https:// 协议,否则生成的证书,kubectl 命令访问不到 apiserver
# a X! ` I2 C$ o6 S
4 |1 w. {6 `$ }! wfor i in 192.168.91.19 192.168.91.20;do \
' E, E1 A7 K6 a2 Hcd /approot1/k8s/tmp/ssl/; \- D2 Y4 _5 s8 O7 `; f
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-cluster kubernetes \! L: }3 l, X. S3 K' ?- J: |
--certificate-authority=ca.pem \- M; j# d2 Y1 Z2 ?+ O- B
--embed-certs=true \
5 Y, @2 b+ M7 D3 _: f--server=https://192.168.91.19:6443 \
& n; {! {$ V) ~- r- W--kubeconfig=kubelet.kubeconfig.$i; \; u5 w& b) }6 E1 [3 G
done/ H% |7 i- X# ^
设置客户端认证参数! h8 @+ _+ }% W/ B
- D+ m8 w! @: E, t0 ]# \' e/ O5 a
for i in 192.168.91.19 192.168.91.20;do \
8 g5 w3 K- P9 _- zcd /approot1/k8s/tmp/ssl/; \) s( d+ Z/ j! Q" V P4 U
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-credentials system:node:$i \" j5 Z( {! `# B, [
--client-certificate=kubelet.$i.pem \
( O6 x7 @! g5 \7 u+ a--client-key=kubelet.$i-key.pem \/ [4 L+ u6 N1 I7 V- ], A% t8 @
--embed-certs=true \( z0 f+ |% S2 W
--kubeconfig=kubelet.kubeconfig.$i; \( n4 ]6 Y, w$ @6 ?" f6 v
done
; b1 a) k# V7 f! D设置上下文参数
4 v: O) e+ D" Q. {
* `0 B' `* _/ g# ]( kfor i in 192.168.91.19 192.168.91.20;do \
+ k# H4 U# i& m5 c. v& Ucd /approot1/k8s/tmp/ssl/; \# B' U0 w/ F! X; Z" V% y
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-context default \
. G5 A- N! ^, y# Q& l! x--cluster=kubernetes \
, n/ O7 x5 i F, O5 S--user=system:node:$i \
( R! M/ W) ]. T4 j$ F--kubeconfig=kubelet.kubeconfig.$i; \! J0 f9 ]7 m4 S8 Z3 o o" u3 d
done
& G: h3 z2 w ~4 ]) P/ S设置默认上下文) D n5 R u3 k
. ^6 F7 q: P8 u4 s
for i in 192.168.91.19 192.168.91.20;do \
" e% u! c$ k3 Q/ { Rcd /approot1/k8s/tmp/ssl/; \" X5 w. t$ `0 E9 y* F* E
/approot1/k8s/pkg/kubernetes/bin/kubectl config \
6 H/ @' {4 c( Z4 k/ N/ |7 guse-context default \- O, a1 k" ~7 b" N+ z! V2 `
--kubeconfig=kubelet.kubeconfig.$i; \6 u3 g# y; y+ R# U$ Y% m4 Y
done
: d+ @# A7 s1 n; w, Z+ ~ I配置 kubelet 配置文件* h9 L$ R/ H; G$ T
vim /approot1/k8s/tmp/service/config.yaml; n) m- Z% f* E( g2 D, @
clusterDNS 参数的 ip 注意修改,和 apiserver 的 --service-cluster-ip-range 参数一个网段,和 k8s 服务 ip 要不一样,一般 k8s 服务的 ip 取网段第一个ip, clusterdns 选网段的第二个ip/ g4 g* {& S- P/ d2 q
: d8 J6 G3 S2 I) V# J7 q3 H; V# Tkind: KubeletConfiguration
% ^4 \) d8 r" T) G( F- b( s2 Z$ papiVersion: kubelet.config.k8s.io/v1beta1
0 C7 Y4 V! h, g& c- U8 Q- [address: 0.0.0.0
) y- M# E: ?! c6 R4 B3 Hauthentication:" Y% x& r5 ~- Q D) } u; f, C
anonymous:! r" B |$ i# L, X
enabled: false' w: k/ u/ B% M
webhook:* i1 I9 \ I7 U) i
cacheTTL: 2m0s
" Z4 J( F6 D" f- n8 M enabled: true: A' q: S4 W6 o2 T5 H
x509:( _8 Q( S7 {) m1 {: b4 D
clientCAFile: /etc/kubernetes/ssl/ca.pem
4 G+ M6 B; F; r0 P+ mauthorization:
) P2 s0 E* ]* b) h: W mode: Webhook( R% V4 [: `+ ~9 i( C
webhook:/ f. ^1 |# A' V
cacheAuthorizedTTL: 5m0s2 x6 u+ I) b1 b
cacheUnauthorizedTTL: 30s3 ]1 r' Q) v9 o! z7 B2 u5 C% r$ `
cgroupDriver: systemd
# |7 Z6 K0 Y V* ~9 `0 N; `cgroupsPerQOS: true/ V& [5 J3 I) n$ O4 p& ]7 ?
clusterDNS:, t& \ ~! j) k' U" X
- 10.88.0.22 n4 c! u0 V- ?7 e! C
clusterDomain: cluster.local; R+ B3 v- R ~6 P9 Z
configMapAndSecretChangeDetectionStrategy: Watch5 o7 i, S* X$ y
containerLogMaxFiles: 3
3 B8 i+ U: I% h; ^4 ScontainerLogMaxSize: 10Mi( i; b: [3 h8 @* u) z
enforceNodeAllocatable:
; R2 ?3 j; ^% ~. m/ A* e, B8 H, I- pods
) r: G3 x( d% deventBurst: 10" i( x) X8 ^8 t7 j$ F( N+ {
eventRecordQPS: 5
% u" g) B; n! D, v5 bevictionHard:2 w5 @7 Y' K: t8 r% j! s: h
imagefs.available: 15%( H6 @; A! w$ W# X6 s
memory.available: 300Mi
. ^; i) u; \1 J4 T. n. V nodefs.available: 10%
~& p& ?6 M1 ]# G7 H nodefs.inodesFree: 5%6 y/ e' T* {6 K/ n, q d
evictionPressureTransitionPeriod: 5m0s
9 S7 {) F% |& z) `/ |2 jfailSwapOn: true
. t0 n, ^3 h. |: l. G+ K9 V1 Q3 o# TfileCheckFrequency: 40s
+ W0 P1 X) K6 p" B6 m& BhairpinMode: hairpin-veth
. ]) C9 O* s. \healthzBindAddress: 0.0.0.0
/ @0 r/ c1 D8 Y0 x; GhealthzPort: 10248( k: C& f$ M$ Q+ S; d. v( ^
httpCheckFrequency: 40s
\- N+ B" ]0 a- M, T! e: |5 HimageGCHighThresholdPercent: 85
M8 M- n; h5 q }$ b/ t1 j. J/ QimageGCLowThresholdPercent: 80/ x2 I) G2 o1 W! k
imageMinimumGCAge: 2m0s) d1 j. @' j7 z9 i# e
kubeAPIBurst: 100
' w6 q1 l2 y" E7 c5 E2 IkubeAPIQPS: 500 _. @! S( N1 K/ V1 @' S: S6 t2 w
makeIPTablesUtilChains: true! v% o, j, `. z- k8 h' q
maxOpenFiles: 10000005 ?' Z" ~) k' u- {# D/ A3 a( ~
maxPods: 1105 V# L+ `* \- S6 `
nodeLeaseDurationSeconds: 40) w) x8 k7 s, e0 [7 n
nodeStatusReportFrequency: 1m0s
1 ?8 _) T; q4 [nodeStatusUpdateFrequency: 10s
' f$ Y/ o! \0 V% h, W1 [oomScoreAdj: -999
2 Z' y. O' k: t" Q/ d; M: S' |podPidsLimit: -1
8 i. P) Y$ V8 }6 R* qport: 10250. {2 @" A) g o6 p. M6 g9 L0 }3 ?# G- d
# disable readOnlyPort' R$ i1 J t1 f p6 ]' k
readOnlyPort: 0$ f1 X. a: N4 `7 B9 I
resolvConf: /etc/resolv.conf/ e0 w* P7 d. d5 Q& |; k+ d
runtimeRequestTimeout: 2m0s
, o( L1 {& K, b$ q; v* f( o7 qserializeImagePulls: true' N, |' O6 m# Y
streamingConnectionIdleTimeout: 4h0m0s+ h. M! f5 M8 J1 J/ J; ^) u1 \
syncFrequency: 1m0s
7 z' `9 ]' {, ^' F1 m* r: QtlsCertFile: /etc/kubernetes/ssl/kubelet.pem$ f* J5 P) O; X
tlsPrivateKeyFile: /etc/kubernetes/ssl/kubelet-key.pem
4 b8 W: n6 A% t$ `" `配置 kubelet 为 systemctl 管理
! u6 O! }3 r* R2 {0 w+ e: v2 w" jvim /approot1/k8s/tmp/service/kubelet.service.192.168.91.19: @" ^% t; x- G7 d5 [3 ~! M
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴,有多少个node节点就创建多少个service文件,service 文件内的 ip 也要修改为 work 节点的 ip,别重复了
9 D' d2 M; I6 j7 U. ?, h
( @, Q- [! k, D2 \--container-runtime 参数默认是 docker ,如果使用 docker 以外的,需要配置为 remote ,并且要配置 --container-runtime-endpoint 参数来指定 sock 文件的路径 V& S/ ?6 n) f; Q4 A
4 m2 r! Y" Z$ x! g) lkubelet 参数
$ ]5 x) ~( b. z1 U) I# Q8 \3 M8 K& \
[Unit]
6 X* t4 ~: M4 W w7 i6 |+ T+ P+ `Description=Kubernetes Kubelet, \/ b8 f a T$ b8 t% M/ o3 _
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
0 L1 m6 v' e( H# _/ D0 ], r' V
[Service]
! @( j7 `! Q4 n" j; eWorkingDirectory=/approot1/k8s/data/kubelet
$ K. G$ s. g( ~# t3 R' DExecStart=/approot1/k8s/bin/kubelet \1 L) {; I5 y, S" x/ t/ W5 @0 C& [
--config=/approot1/k8s/data/kubelet/config.yaml \
8 f( [! ~! y, v# x r7 U) ? --cni-bin-dir=/approot1/k8s/bin \) E8 y$ @6 u" F( E: w
--cni-conf-dir=/etc/cni/net.d \
2 \' H7 O6 G0 ^8 {) u* Z" h1 p --container-runtime=remote \" c3 c4 a0 Y) G# o2 M) m0 n
--container-runtime-endpoint=unix:///run/containerd/containerd.sock \
+ A" k' \9 a7 y5 T4 A @; [ --hostname-override=192.168.91.19 \
8 ~1 s% x+ I4 r1 x7 p8 g+ L --image-pull-progress-deadline=5m \% j4 S) C/ {; z% u# T8 a) a
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \* [7 G" F2 R5 `+ O
--network-plugin=cni \
' v9 q0 _- V3 w$ U! t1 p1 a --pod-infra-container-image=k8s.gcr.io/pause:3.6 \
" L! V" J6 K' f7 v* m$ | --root-dir=/approot1/k8s/data/kubelet \0 e' a' M1 g/ ]: H j7 H
--v=2
- u: c4 n9 G" _6 O" `% |' M$ LRestart=always$ J8 U' ^- h) m' ^+ l1 v c& O4 ?
RestartSec=55 L# o. \ T5 \# M; i, p' t, L" |
) y* q' A6 W& g# a[Install]
5 u( S- F3 v- A: X/ ^5 qWantedBy=multi-user.target
6 S" r* G; [5 x [& I, ~分发证书以及创建相关路径
" ]7 h& {4 c4 ]- a7 w如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制
4 O% E' G. H! \, L% `* q6 ^, r9 H: X: [6 e9 e4 z' E; F
对应的目录也要确保和自己规划的一致,如果和我的有不同,注意修改,否则服务会启动失败/ b+ R- t% U1 \, e
- P# ~) w2 m1 m% i' W6 L3 A
for i in 192.168.91.19 192.168.91.20;do \1 |3 i1 E5 x! u# U- o- S" s
ssh $i "mkdir -p /approot1/k8s/data/kubelet"; \5 N% l$ P; f9 m$ N" ^9 l; r! e
ssh $i "mkdir -p /approot1/k8s/bin"; \
3 @) X! M! h9 j2 T" ^ssh $i "mkdir -p /etc/kubernetes/ssl"; \
& k6 l# s% B; L, x1 B- j; R( Dscp /approot1/k8s/tmp/ssl/ca*.pem $i:/etc/kubernetes/ssl/; \
- p8 i$ Y* I$ I& O7 {5 h; nscp /approot1/k8s/tmp/ssl/kubelet.$i.pem $i:/etc/kubernetes/ssl/kubelet.pem; \
% R% I4 o! x6 E5 T! l( i5 m/ Gscp /approot1/k8s/tmp/ssl/kubelet.$i-key.pem $i:/etc/kubernetes/ssl/kubelet-key.pem; \* K8 |* J9 R4 {% t
scp /approot1/k8s/tmp/ssl/kubelet.kubeconfig.$i $i:/etc/kubernetes/kubelet.kubeconfig; \
# G0 [2 [ I- E9 ^; @3 m5 N3 _scp /approot1/k8s/tmp/service/kubelet.service.$i $i:/etc/systemd/system/kubelet.service; \/ A4 M' V |( w2 L
scp /approot1/k8s/tmp/service/config.yaml $i:/approot1/k8s/data/kubelet/; \! S: Z, m/ c8 R* U# B4 E
scp /approot1/k8s/pkg/kubernetes/bin/kubelet $i:/approot1/k8s/bin/; \9 h/ C1 b5 v+ E
done
, x3 r, Y7 H; |% h) N启动 kubelet 服务
! I% B% \/ O8 Wfor i in 192.168.91.19 192.168.91.20;do \4 b% h% l( l7 F
ssh $i "systemctl daemon-reload"; \$ W, s5 |4 N9 s% G+ ?' t
ssh $i "systemctl enable kubelet"; \5 g8 y2 G) ?; D" \+ B8 d
ssh $i "systemctl restart kubelet --no-block"; \
2 z/ I6 i C9 f3 Cssh $i "systemctl is-active kubelet"; \
; Y$ W: ~# Y: W6 V; H7 W' G( k- `done3 i& s" b7 [2 e3 p3 I
返回 activating 表示 kubelet 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19 192.168.91.20;do ssh $i "systemctl is-active kubelet";done) ^# Q! z- z/ L
0 v, V6 u3 h8 j2 |返回active表示 kubelet 启动成功5 i1 Q. @# g- N4 {7 v
j- W" |4 V8 H9 ?& B查看节点是否 Ready
1 Z+ a$ n1 X7 B9 akubectl get node
2 r% n1 P. ]! x5 L; Q预期出现类似如下输出,STATUS 字段为 Ready 表示节点正常! }; d6 n! v6 }2 |1 Y) p
2 e F0 w; E( M, FNAME STATUS ROLES AGE VERSION
2 n5 J0 g- H* {192.168.91.19 Ready <none> 20m v1.23.3' b; `0 Z# v8 y! L! u v, m8 @
192.168.91.20 Ready <none> 20m v1.23.32 R8 P8 B- @+ F
部署 proxy 组件
+ g7 M& Y# |! ^ k7 k! Y创建 proxy 证书0 b z4 C; c C: l
vim /approot1/k8s/tmp/ssl/kube-proxy-csr.json
1 X! j& x; |0 Q" ~( Y6 d{
- E1 ]( n6 z* k* e# `5 Y "CN": "system:kube-proxy",9 V( `' r/ C6 Q1 W$ l/ E# l6 y
"key": {2 ~4 O) A2 p5 |; B. Y* ]3 ?
"algo": "rsa",/ s( p S Q/ D" k4 Q/ e& C9 j7 j! L
"size": 20480 ^- k9 q+ @/ g% M' I1 u+ {
},6 L! D8 X# q; d5 D9 c& Y
"hosts": [],1 y- }! A: P) [1 y! }- {
"names": [
" z' g* C9 f6 l! M$ c( |% Q1 j {3 U) O( _5 f3 T9 j
"C": "CN",
$ P1 C+ g5 k" B2 r7 ~4 |; s/ T "ST": "ShangHai",
3 A5 U4 E. l1 c6 @6 h. ~ "L": "ShangHai",3 {5 q P9 { O7 H- o$ y* L
"O": "system:kube-proxy",
+ b' B$ v# g b0 x6 d7 s "OU": "System"/ H; y( m9 f: ]' g
}2 S6 P% a; M+ \. l1 P" Q+ T
], O" ]! I5 B9 o
}
) h \" b1 Y. {cd /approot1/k8s/tmp/ssl/; \- s4 |7 n0 F2 s+ G- q
cfssl gencert -ca=ca.pem \
/ T0 V+ P2 p7 d& x: o; @) u; |-ca-key=ca-key.pem \ d/ k! k1 s: I1 ]- r* K; a) ~7 |
-config=ca-config.json \
: ?! M' n, X3 n) `# D-profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy6 D$ p' }8 b# r* v/ \8 Q9 Y& \
创建 kubeconfig 证书
- p! R" L0 Q& q: p设置集群参数
+ P% U1 Z2 u$ H7 v
/ M$ f: E, X$ |* Q q" i3 J# [--server 为 apiserver 的访问地址,修改成自己的 ip 地址和 service 文件里面指定的 --secure-port 参数的端口,切记,一定要带上https:// 协议,否则生成的证书,kubectl 命令访问不到 apiserver
- e, t9 n& X8 i; r5 d0 k
: d& o9 {7 H* `# U3 T% _) \& ?cd /approot1/k8s/tmp/ssl/
/ @, _* D5 V' H) y7 f+ p5 a/approot1/k8s/pkg/kubernetes/bin/kubectl config set-cluster kubernetes \
7 Q& S" L- ~: b- o--certificate-authority=ca.pem \( t9 b6 [! k; ?5 l* c1 s0 K
--embed-certs=true \
0 b, J* Q3 B6 e. N--server=https://192.168.91.19:6443 \: \4 U, o5 O; d6 T- j# C& V t
--kubeconfig=kube-proxy.kubeconfig9 s) V9 ^, k ~) m7 u
设置客户端认证参数0 _7 E) Y, a* `* x2 x
+ }: ^, W* j' i$ ?6 N
cd /approot1/k8s/tmp/ssl/
& F/ ^9 P' V0 q$ B/approot1/k8s/pkg/kubernetes/bin/kubectl config set-credentials kube-proxy \! t# W7 A! |' M3 z
--client-certificate=kube-proxy.pem \/ d4 X" n4 o! O5 y0 e
--client-key=kube-proxy-key.pem \
2 F! V: j+ P/ V ]9 ?1 I9 B--embed-certs=true \' I& e n+ F8 a( X# ]. t; q
--kubeconfig=kube-proxy.kubeconfig0 M) x0 h' ^8 s, h$ @* h
设置上下文参数& h; s: W- }% o1 U
/ {1 @* i6 t. Jcd /approot1/k8s/tmp/ssl/2 l' F% l m6 k, x8 x3 @
/approot1/k8s/pkg/kubernetes/bin/kubectl config set-context default \
. e) h1 k6 ^* b2 e; l- x; ^( }--cluster=kubernetes \
4 o/ Z7 V& W) b! u( ?0 K' _5 E--user=kube-proxy \- y9 P. g7 \, k2 a( }
--kubeconfig=kube-proxy.kubeconfig
) G2 {% _, ^: l6 G9 c6 W设置默认上下文, }4 N+ [% \) x" e* F
- x" x% D) u I/ K2 ~" B* Q3 S) ?
cd /approot1/k8s/tmp/ssl/
& U6 Y3 k" q/ ~/approot1/k8s/pkg/kubernetes/bin/kubectl config \4 v9 c3 k; e q$ {
use-context default \
, C: X9 j* ~* x7 l6 c/ Y--kubeconfig=kube-proxy.kubeconfig
: Y7 ]+ p) j9 r9 @( s1 L6 v. p1 C配置 kube-proxy 配置文件( g3 `3 j- p9 W+ Y% p
vim /approot1/k8s/tmp/service/kube-proxy-config.yaml.192.168.91.19& s1 n5 \/ l* ]7 S$ R8 S& C( X, D3 x4 Y
这里的192.168.91.19需要改成自己的ip,不要一股脑的复制黏贴,有多少个node节点就创建多少个service文件,service 文件内的 ip 也要修改为 work 节点的 ip,别重复了" G/ z- b( i$ U4 w4 e
V0 V7 t) e! R' rclusterCIDR 参数要和 controller-manager 的 --cluster-cidr 参数一致5 O6 V( o$ t- C) T5 B8 A7 j
; R1 O2 S( e0 Y j3 xhostnameOverride 要和 kubelet 的 --hostname-override 参数一致,否则会出现 node not found 的报错
$ r8 S) ^' b! G$ u7 r
. `! t8 v3 T- w) t. W% T4 nkind: KubeProxyConfiguration
& S( X6 Q [( x2 ]apiVersion: kubeproxy.config.k8s.io/v1alpha1
O# z- i$ ?; w( } ZbindAddress: 0.0.0.0: X3 R' h, K0 Q. K( ?+ o" E1 z
clientConnection:# d- {3 s; u2 E. z
kubeconfig: "/etc/kubernetes/kube-proxy.kubeconfig"
* V: q6 h2 Q5 c5 _: i1 u U4 dclusterCIDR: "172.20.0.0/16"
5 G, C) |* ~# h G( uconntrack:7 P# {$ ^- w" w6 u$ S- v
maxPerCore: 327684 J2 i) S- ]) T" f
min: 1310727 a: \. g4 I/ k$ B( J
tcpCloseWaitTimeout: 1h0m0s
& ?6 F( U) x$ s& r tcpEstablishedTimeout: 24h0m0s
* K0 \0 ~5 ~7 p0 m7 R0 |6 k! b. qhealthzBindAddress: 0.0.0.0:10256% s! \9 n5 l# ]- z4 \
hostnameOverride: "192.168.91.19": Y- m8 A) B1 x# m
metricsBindAddress: 0.0.0.0:10249
9 {0 x: ^! V) i8 |/ _, }0 Q9 b9 @; wmode: "ipvs"# u: o3 h6 L, _/ A
配置 proxy 为 systemctl 管理
5 H8 k) c7 g7 t+ a5 vvim /approot1/k8s/tmp/service/kube-proxy.service1 H5 [. v( j" Z- I7 K! ~
[Unit]
) {( U5 Z; U+ u; b' a# w+ m( x" yDescription=Kubernetes Kube-Proxy Server& W; _8 Q/ p3 s; E
Documentation=https://github.com/GoogleCloudPlatform/kubernetes/ x; L- Y2 k5 s n' ?4 X
After=network.target/ P* Y) M9 z& B6 B2 A
; o, l1 V! ]' V[Service]9 i6 x0 D9 ]- z1 m6 x" i: [
# kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量
) U% d. W) I9 h## 指定 --cluster-cidr 或 --masquerade-all 选项后
! @2 `4 ?( i$ W" R9 K) Y## kube-proxy 会对访问 Service IP 的请求做 SNAT
3 Q% u$ G1 v6 a$ D4 dWorkingDirectory=/approot1/k8s/data/kube-proxy- a R: x/ g. ]/ v: D
ExecStart=/approot1/k8s/bin/kube-proxy \) o4 v' R" y* _! w
--config=/approot1/k8s/data/kube-proxy/kube-proxy-config.yaml* b$ Q; S. u* M
Restart=always( f: L/ r; W: ~1 Y, e0 C5 `
RestartSec=5) I+ O0 R9 X) ]
LimitNOFILE=65536( D) _1 Y' ^, [5 g
, c# U6 ]5 B' `[Install]
# k; }0 S6 p' P" mWantedBy=multi-user.target9 T6 {% f( ]/ Q- E6 K" ~
分发证书以及创建相关路径
5 G8 \. k+ s5 b2 z如果是多节点,只需要在192.168.91.19后面加上对应的ip即可,以空格为分隔,注意将192.168.91.19修改为自己的ip,切莫一股脑复制8 [6 d& ~8 H8 I& j
" L8 d* E0 D& o3 d% i* s对应的目录也要确保和自己规划的一致,如果和我的有不同,注意修改,否则服务会启动失败
& U: _: x/ h' q; @) h
6 ]6 y3 ^$ q9 {# f; c8 wfor i in 192.168.91.19 192.168.91.20;do \
& u/ A8 H* u4 G8 a/ O+ \# Ussh $i "mkdir -p /approot1/k8s/data//kube-proxy"; \" O7 X: o9 k2 f3 Z4 c F/ A& |
ssh $i "mkdir -p /approot1/k8s/bin"; \
9 J; g5 O6 O8 A) e' I, f2 H8 ossh $i "mkdir -p /etc/kubernetes/ssl"; \
9 B5 j% B3 d; K6 R! hscp /approot1/k8s/tmp/ssl/kube-proxy.kubeconfig $i:/etc/kubernetes/; \8 \0 j" |; a2 h
scp /approot1/k8s/tmp/service/kube-proxy.service $i:/etc/systemd/system/; \& _* ~$ n1 Z3 q
scp /approot1/k8s/tmp/service/kube-proxy-config.yaml.$i $i:/approot1/k8s/data/kube-proxy/kube-proxy-config.yaml; \3 {) y$ v& k5 k+ f' Z
scp /approot1/k8s/pkg/kubernetes/bin/kube-proxy $i:/approot1/k8s/bin/; \. G9 F' W: k6 M q
done
: k5 d$ X$ p; V启动 kube-proxy 服务
# U! v# z" T4 j, S' j3 m$ N$ mfor i in 192.168.91.19 192.168.91.20;do \6 g9 J9 V2 B8 u* ^9 n& }
ssh $i "systemctl daemon-reload"; \
5 ^3 T* t2 h" V! F, d% Bssh $i "systemctl enable kube-proxy"; \
5 b, E/ g9 C7 ~! o' M7 V" O( @' `ssh $i "systemctl restart kube-proxy --no-block"; \. m3 y7 ]9 \& w* \) v d
ssh $i "systemctl is-active kube-proxy"; \8 _6 e6 ]: Z3 O3 r7 k/ P3 S4 a5 B
done! p/ o+ U* `. l- J* a
返回 activating 表示 kubelet 还在启动中,可以稍等一会,然后再执行 for i in 192.168.91.19 192.168.91.20;do ssh $i "systemctl is-active kubelet";done( S, ? _ v' \3 {& r2 t, W: j
! ]& ~& a- C U6 z" n1 a0 W
返回active表示 kubelet 启动成功/ ?: Z9 T' I, r2 P! b: a2 j6 |1 ?
$ p4 n) \* u2 C( ~% h部署 flannel 组件9 q4 t, G2 Z# o% E
flannel github* E& J5 E6 k: H+ S
. i1 x& S* O2 C& b
配置 flannel yaml 文件: _6 v6 ?3 h4 b/ X- a
vim /approot1/k8s/tmp/service/flannel.yaml
) v5 W( o, X- x7 |net-conf.json 内的 Network 参数需要和 controller-manager 的 --cluster-cidr 参数一致
+ m' u+ w/ j1 {, R1 ~! V+ _4 J% Q' e, h4 Q; Q. ]' j0 W8 {- ]
---
( }6 `5 r ?, B( NapiVersion: policy/v1beta1
% }: t+ F P% Y" z ^0 {% kkind: PodSecurityPolicy
6 g/ q* w) _0 I- B0 y5 Qmetadata:
F9 c: D/ E. p4 P$ H+ _ name: psp.flannel.unprivileged
# U, E+ t2 g5 a0 P; B annotations:
1 _5 Z+ @4 H, w/ V& j seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
" a) U9 n3 @( O seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default* z2 u8 y s5 [
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
" ?! H- E2 G' i, L# ]4 p apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
- a3 a3 ~' ]8 n# i% |spec:
3 D! g; d1 S# Y+ y1 M7 g; y- `6 z0 ? privileged: false, w. T, F8 `+ b. I8 x+ {0 T. K8 Q( Y7 c
volumes:
% b; s5 K/ W$ |1 d* o/ j- J1 N - configMap+ r+ `* E- U4 L3 ]
- secret
+ G( w1 L8 [- h. p$ ` - emptyDir
. X1 Y% P4 L+ c' r. t3 k - hostPath
9 C2 H6 F. j; V" [1 T, X allowedHostPaths:# j% Y2 V6 }! _2 }
- pathPrefix: "/etc/cni/net.d"$ W! ~0 G. }5 K8 v, ?( j# m
- pathPrefix: "/etc/kube-flannel"
9 P9 _2 a) U; u6 q' q- d - pathPrefix: "/run/flannel"8 f# c* @9 w$ Y( E
readOnlyRootFilesystem: false: n0 U" _" Z ]+ _
# Users and groups
- o' e. n+ b3 g& d9 j0 f$ ] runAsUser:
" `, o7 O: F9 L& q8 ], s* q! a rule: RunAsAny+ y+ y0 d0 ^" t, v, }6 |9 ?5 ~; M2 _, ]' [
supplementalGroups:
) H4 ]# s& Y0 |7 i! C% N1 p7 i" C: p rule: RunAsAny3 m7 g r: O% O! e; t
fsGroup:
; }7 @# m1 d: m6 { rule: RunAsAny; K* s- O9 e4 W( ? m% w+ ^
# Privilege Escalation* F: V9 u7 Z) Q; X ^2 m) P, o- D
allowPrivilegeEscalation: false
# D! r5 _. I/ f) g. u defaultAllowPrivilegeEscalation: false
# N; y- u+ q7 f" o # Capabilities
% y/ D! ^3 r; x9 u3 m$ y' r allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
" t: Q: q& ]3 i, ?. |- S( J! M3 j defaultAddCapabilities: []% a4 z* L( \7 q2 S! {
requiredDropCapabilities: []
* {2 K J/ B* I3 M3 n # Host namespaces! S: p7 Y2 a' m/ N7 N# `
hostPID: false+ F @3 U" i: `4 d1 \
hostIPC: false
1 }" t8 ]7 Z; w5 |) N" B2 M hostNetwork: true- s+ n5 M$ Y ]$ p. h9 \
hostPorts:, G5 O4 ^! h2 a! H, k1 u
- min: 0
. p6 K8 ?+ p1 c0 |( k6 n8 T max: 655354 Y5 \7 f! K+ w d* X: Z4 M8 \
# SELinux; k' t: B1 G1 u& Z! u+ C. s
seLinux:
" z7 W N6 J4 ?! W& V7 O # SELinux is unused in CaaSP( _& E2 Y& X2 }* ]+ o6 T3 Z2 y
rule: 'RunAsAny'
( R$ Y- ]0 K u---3 l' B: g! U5 t- p2 W) m; J0 l
kind: ClusterRole% v! @* ]9 V8 @' j' `2 f8 }
apiVersion: rbac.authorization.k8s.io/v1
; c0 X5 z6 D" Umetadata:
% \" h2 p, _8 ?5 w" c5 `6 P name: flannel
; P" I" B2 R2 ^rules:
. n4 `7 w+ b2 e! r+ J+ o" l/ t7 Z- apiGroups: ['policy'] J8 E; m- {9 X3 E2 R
resources: ['podsecuritypolicies']
4 ?* o) m/ ?7 A# y" _; N5 j verbs: ['use']
* r: p( N( ]' r, K- c resourceNames: ['psp.flannel.unprivileged']5 r7 X) d5 }! c' P3 I1 m& Q) g
- apiGroups:
% h6 u4 Y6 I8 \% L - ""+ J3 f/ l, o5 T/ H' K3 o- G
resources:+ [8 T3 U& Z7 u
- pods
: ~: D0 i: @ _; j( O verbs:( _2 l% @5 a6 t2 v
- get- v# Z* M' @, H; t
- apiGroups:) e; r# Q" M! b8 }! d) q
- ""
# e; c9 |" w/ A5 F3 x& J8 X resources:9 B- z9 ~" _* u
- nodes9 U, z% t6 ]- f n% K3 u, ]: s
verbs:
8 O7 H6 _& ?- E: q+ ` - list0 a0 X! t+ }- W+ k# n
- watch
. X4 G3 A# g3 [; ]5 i- apiGroups:
/ K( ]- L( k G - ""1 ?5 U( F8 }: F1 g+ d; h* q* i
resources:3 a& F. z/ Y9 G8 n
- nodes/status
2 ^% Q! l; N- b: p+ W( J- f verbs:: H3 p; d/ z9 c
- patch
9 y' z; t7 {7 l }---! f: `% P) ]6 ]
kind: ClusterRoleBinding4 F: a# i( j4 Q) A& M
apiVersion: rbac.authorization.k8s.io/v1- U) D6 o# @' w0 g7 P; p
metadata:
/ J4 ]% f, @4 s% V( L0 B name: flannel
6 z4 {9 x, S- W/ |% s8 Q! t8 YroleRef:- L( ]* Z+ W' g. m
apiGroup: rbac.authorization.k8s.io
8 O. |& D: v8 G+ R1 a& p: T kind: ClusterRole
+ e: P6 W+ l" [( q9 g+ X, U name: flannel' I& ^: V6 ^ l* ]
subjects:
0 D6 i. x" T5 _8 t7 Q- kind: ServiceAccount5 h% j8 I6 u+ C( ?
name: flannel
9 }0 ]8 S; n; z" d, i. u- d namespace: kube-system
. a8 e" s, Z' j4 t# s2 l---/ |$ P7 o. C4 ]1 s
apiVersion: v1
& P1 p' k$ b. L/ L; Bkind: ServiceAccount
. M# `6 S/ l8 }0 n- g$ F) o6 G# [metadata:
( H+ h% `2 J/ g2 Q/ k) u name: flannel
2 O" i- B% F$ n3 s, L) \/ b namespace: kube-system2 Y% i$ F/ \* R0 [5 {6 j. J9 C- _
---
; E/ G" n0 L9 \; H0 [$ E. T P8 Dkind: ConfigMap! _" t% `1 p' p# `
apiVersion: v1
; k2 d4 z8 P4 f0 ^& X9 m0 @metadata:1 M! t( {9 _7 P
name: kube-flannel-cfg
# k5 p4 m2 K, r) _5 U namespace: kube-system+ @/ f8 ~. @; I6 ?! M
labels:6 r# G% w% [/ ~* u' o( `9 b8 T x0 o
tier: node
- X& H7 v1 R1 m0 `, j app: flannel" f7 |! R0 l. l/ v ~3 l" O3 d3 I* w; {
data:% M: n; M( B, j- y
cni-conf.json: |1 p4 j( b: m* I0 F6 s! G
{
+ \6 A# r: K( k3 h p' e( e* n "name": "cbr0",
7 b+ q* J( M) d# E# J, W1 Y "cniVersion": "0.3.1",4 v+ G/ ^1 G5 @- p
"plugins": [
' |; p$ i: B7 b* ~6 A. ^ {
& ]6 h' }( ]4 z "type": "flannel",& e; v& k5 H3 t1 v; j
"delegate": {
( j9 \: L. [' J8 {5 E "hairpinMode": true,
1 d6 B2 o: J0 g4 @% b8 A$ A$ W9 [ "isDefaultGateway": true1 R% s( e) X3 @8 k0 R% J" E1 H! q
}0 \4 Z3 _& y) n
},1 u5 I" {, t/ R4 n) \2 I
{/ P, U3 ?# O# s1 O; X( I
"type": "portmap", G d: @7 J5 @. i3 u; l( T
"capabilities": {$ \; y7 c2 H8 L" H) U9 K" J3 s
"portMappings": true- R/ G" j/ |$ }# i6 n
}+ M. X, U8 v3 B% W W( {+ e
}0 S, x8 i3 W' I; o4 p
]
7 s1 }% r, y4 P0 T" V2 J$ K }
, N7 n& W$ k4 U0 H* e net-conf.json: |6 K7 `/ ]2 L+ @2 d B
{
; T9 J1 v& D. V/ H "Network": "172.20.0.0/16", D. ]2 i' q5 `, p) }
"Backend": {
% N u ]! ~ C/ H! U8 ]$ a+ y "Type": "vxlan"9 }( B3 Z3 I L/ _9 Z A
}
{: y7 K% Z9 t& w2 E }
. V, E) P$ N6 E) Z- n4 a---& ~; M' j, N* k c) T+ p3 T$ o
apiVersion: apps/v1
# A7 N: h( S& B7 j# C' dkind: DaemonSet/ V6 S* Q! v7 C; T) Z/ K4 V G
metadata:
! }& [, I5 U: k2 z+ F name: kube-flannel-ds
; A/ f- F: Z7 t# y% P namespace: kube-system
f$ D! e# J/ h8 p/ ^ labels:
. H. i. J& y+ R0 } tier: node1 \+ D/ K& @% _7 U6 X2 m
app: flannel
3 A$ F3 [/ k4 @spec:
1 Q1 z4 ?0 g ^ g! E$ |/ v7 G | selector:
Q! C, p. K l matchLabels:5 v; t, Q( x' B- J( U: _
app: flannel* a5 b6 F- \6 n2 ?- Q! m: b
template:9 w6 o3 i. a5 o. X
metadata:; M- Q& w" O! k
labels:+ a1 @9 a$ A6 ?3 w; v9 i- O C) `
tier: node
1 ]6 A, t$ L0 V+ f; K; j app: flannel1 j3 B1 g5 @7 X
spec:% O4 Z5 K& F3 Q5 J3 K4 n
affinity:
" a9 S" f2 H7 G) u2 u1 j nodeAffinity:3 A) Z- S1 [# N. |. a9 @8 @; D( B
requiredDuringSchedulingIgnoredDuringExecution:
- A n( K7 @/ C: Y nodeSelectorTerms:
9 `# c+ B s5 V0 c; ~ - matchExpressions:& y0 e/ E- S* D* r+ R
- key: kubernetes.io/os
. ?5 m9 u E7 p1 _# j+ v operator: In" M( B2 u A1 ^. d! o: O
values:
6 o& U; M) ^' J" ?1 }6 c g& `/ d+ q - linux1 I8 W7 j" y$ u
hostNetwork: true
- \7 G: D. }/ m priorityClassName: system-node-critical
. G3 X0 f6 Z8 R2 a# } tolerations:. o, p1 g! T4 p: {1 {, D8 D5 X7 `. @6 O
- operator: Exists
* w, h' ?3 B. i% A effect: NoSchedule5 p. L" g# m3 u) P
serviceAccountName: flannel# M) b; _& }! f. w
initContainers:' `! q9 h) x4 q
- name: install-cni0 j/ U) ]3 K0 ] l3 |
image: quay.io/coreos/flannel:v0.15.1
: }7 @3 ]$ l9 K7 ^5 k' g( @ command:4 C* w5 t* J4 a F9 |
- cp
3 `/ G @) }) F+ C args:$ g2 ?; \, W6 K" s \6 x2 f
- -f, c( a3 h1 @! m* y6 ]8 m
- /etc/kube-flannel/cni-conf.json0 p$ u u& d: Y7 h
- /etc/cni/net.d/10-flannel.conflist
. a9 A3 ~: l7 s; U volumeMounts:! W- i" R' B" r/ F* w% Y2 q6 f9 g
- name: cni2 r8 o0 Z* `% C5 u/ c2 l
mountPath: /etc/cni/net.d
- M" F+ U5 ]. e" E& H, |7 `8 N - name: flannel-cfg: `4 V: e: J& \5 F+ T2 ?# K/ u
mountPath: /etc/kube-flannel// O! d' B }/ U0 D, c& T! m+ A
containers:1 K: z2 ~ G2 ]" o' h. s
- name: kube-flannel
. Q) o: d" L% L( B y; Y7 t image: quay.io/coreos/flannel:v0.15.1& g; v2 `, R0 F8 |$ [
command:6 V5 P( ^3 G6 V; `. F# m
- /opt/bin/flanneld
9 P5 F9 o5 h0 G+ [' K1 ~4 G args:
" G3 b4 a3 a3 d! v9 g3 f/ V - --ip-masq2 p4 J2 ^9 h2 |+ R
- --kube-subnet-mgr
5 b6 j& \& F7 b: ~5 i" b& L resources:
$ X5 d% [! D0 d% d. H requests:" t( i7 `* e4 |. F% [% \
cpu: "100m"8 k: X2 ~$ J2 @9 y# o: z! C5 f1 F$ t- q! |
memory: "50Mi"
0 k( f* s& J7 H$ T9 N: A% G limits:% ]/ J& x8 C9 f0 D: s
cpu: "100m"6 M [ Q8 q& w O/ R: G' f) y( }
memory: "50Mi"
2 c- J/ V8 t8 q7 ^4 k2 o( [ securityContext:( t" t( w4 R1 Z; m% _- ]
privileged: false
6 d$ ?1 w7 A" p1 e% y2 S5 x capabilities:
. H& F) G" G$ |- q1 n( [' f add: ["NET_ADMIN", "NET_RAW"], P5 @! y6 ~. d/ g+ `( C- W4 s& {4 n
env:( Z" M+ f- E. r) b5 N! j
- name: POD_NAME8 P1 j3 s) `0 u0 V* v
valueFrom:
- Q6 ^6 c+ ?+ V1 ]: v1 g fieldRef:
0 ^" X( x) N( A1 G% _ fieldPath: metadata.name2 Y; L5 o% c: ]
- name: POD_NAMESPACE8 Y% q/ w) `7 ]% a" v. ~2 W1 y
valueFrom:
. S& e! f$ _# Q fieldRef:) h2 S4 @ P* P. ]! {! e
fieldPath: metadata.namespace R' f$ H! K9 x' G7 I
volumeMounts:# f" x7 T9 p. d; F( E
- name: run
' h% T# g) e/ E2 Z- o- t. W' N mountPath: /run/flannel
! [; K1 S, d: a1 b4 m+ p! h - name: flannel-cfg; I; O& d- x' L% s1 o+ z* b
mountPath: /etc/kube-flannel/
, ]4 _) _, X; |2 S" f4 v3 K volumes:7 c3 j& F7 J3 ?3 M9 Z
- name: run
$ o6 m2 Z+ A- ?/ k! H hostPath:8 a9 B6 J8 H- i3 s
path: /run/flannel( l& H e# k( x4 ^7 e% M5 w$ w
- name: cni( Q/ Z! h# T1 }5 _% |
hostPath:+ G3 a ^5 X1 v4 w
path: /etc/cni/net.d! D. R9 j3 n R h- e; n
- name: flannel-cfg& y# o( w3 G$ M9 d- O: y$ U
configMap:; R+ [7 v$ p4 m5 \0 W9 V7 P
name: kube-flannel-cfg4 y0 B$ h. w$ q
配置 flannel cni 网卡配置文件
: i. n: H0 a3 h% l" wvim /approot1/k8s/tmp/service/10-flannel.conflist7 B% @# j0 ]5 n/ L$ q
{
8 { N$ [' M/ g+ b# }4 _8 o; Q "name": "cbr0",
4 ]) B& b% V3 r3 x, R0 X/ q: M- D "cniVersion": "0.3.1",( ]5 F4 `5 _9 c5 @* p: J) f8 b. e
"plugins": [
b& P }7 y7 Q' W: i( {2 M. u {
7 x. ?6 C) |2 \3 Y+ u "type": "flannel",5 U0 V; e# @! L+ J
"delegate": {% L/ h6 T% y8 g4 O+ s: Z7 a& u. _
"hairpinMode": true,9 f8 j" _6 A" [0 `+ ~% O
"isDefaultGateway": true# o+ r# G4 e3 ~3 \- Z: k; ?+ T; \
}
- g, G9 k4 R! B. u },
1 x4 I5 \/ f' i# ?4 w* T4 ? {$ b0 x, u% H9 D; w' D( s
"type": "portmap",
- @# D5 p2 m1 g+ `) I "capabilities": {1 L$ v: F- m& V# t
"portMappings": true
0 c C* V9 f6 ?3 ?: Z* k7 y' H3 z" I }# \$ f9 P+ A2 M8 ^
}7 b9 C# u# @2 k8 }% w" w Q# y1 R
]; Z. W- |/ P: ?1 F
}. ?+ L' K/ N, o2 j" y: s0 `
导入 flannel 镜像
( Z- c( j* v; |) C! w2 Jfor i in 192.168.91.19 192.168.91.20;do \
7 }/ ]0 ~5 [8 J7 ^- e2 o* Z: J- B- gscp /approot1/k8s/images/flannel-v0.15.1.tar $i:/tmp// ]6 E. Y- p+ C. ?
ssh $i "ctr -n=k8s.io image import /tmp/flannel-v0.15.1.tar && rm -f /tmp/flannel-v0.15.1.tar"; \
( C7 @4 `1 q3 ]$ R* w) xdone% M! f& i8 Z9 ~) r" U. q
查看镜像+ @* ?! r. _7 V8 ^* ]3 Q
* ~& a4 G3 u" a/ N2 H9 [* C+ U, Tfor i in 192.168.91.19 192.168.91.20;do \
& [! w% p( W) w4 H1 [, r$ L7 q' S- }ssh $i "ctr -n=k8s.io image list | grep flannel"; \. k9 u( l' H. n' n
done* Z& Q" k7 A* u" Z8 B0 l# j7 n
分发 flannel cni 网卡配置文件
& g$ d* `4 f% t ~! Sfor i in 192.168.91.19 192.168.91.20;do \
1 F5 K% G/ M2 Y5 c! Cssh $i "rm -f /etc/cni/net.d/10-default.conf"; \( ?0 p8 F" q, A f" w/ K
scp /approot1/k8s/tmp/service/10-flannel.conflist $i:/etc/cni/net.d/; \. T/ D* m: H: l7 Y7 S9 F8 k5 I
done
. p& K4 j2 Y+ S6 L分发完 flannel cni 网卡配置文件后,节点会出现暂时的 NotReady 状态,需要等到节点都变回 Ready 状态后,再运行 flannel 组件' G0 b+ T+ G. }; u+ C% ?/ k6 f6 {- V
! L5 H) `# A& E& p0 t5 M7 ~+ Q在 k8s 中运行 flannel 组件
& \4 j6 z: P% n. l2 V& o# e! Skubectl apply -f /approot1/k8s/tmp/service/flannel.yaml
7 ~. g U. w" `+ o; C5 [6 j检查 flannel pod 是否运行成功' M7 ?, d4 i( q
kubectl get pod -n kube-system | grep flannel1 R1 k; L& Y1 ~7 P1 x
预期输出类似如下结果7 v$ X( V- I% y6 c/ u# q
! X) v7 g) w! _; w8 X/ ~flannel 属于 DaemonSet ,属于和节点共存亡类型的 pod ,k8s 有多少 node ,flannel 就有多少 pod ,当 node 被删除的时候, flannel pod 也会随之删除
) h L. \9 _. _7 o0 A; a) C/ x# e- J8 `; `
kube-flannel-ds-86rrv 1/1 Running 0 8m54s
% w' O L# U! G+ `2 @( k+ q& v4 Jkube-flannel-ds-bkgzx 1/1 Running 0 8m53s6 i9 j4 P) Y3 s$ {& ]) ?2 E% c
suse 12 发行版会出现 Init:CreateContainerError 的情况,此时需要 kubectl describe pod -n kube-system <flannel_pod_name> 查看报错原因,Error: failed to create containerd container: get apparmor_parser version: exec: "apparmor_parser": executable file not found in $PATH 出现这个报错,只需要使用 which apparmor_parser 找到 apparmor_parser 所在路径,然后做一个软连接到 kubelet 命令所在目录即可,然后重启 pod ,注意,所有 flannel 所在节点都需要执行这个软连接操作& W3 a: l- B' T; X2 f' n2 a
' U# z, I3 m* `( i) @6 v- \
部署 coredns 组件
5 b' _& W a/ d V |# C配置 coredns yaml 文件8 f- s6 y L2 |5 y6 C
vim /approot1/k8s/tmp/service/coredns.yaml
4 ?. H7 d3 V+ y. C$ c2 I3 dclusterIP 参数要和 kubelet 配置文件的 clusterDNS 参数一致( S& e1 g% N# j
* e% k8 Y+ s6 I3 \' t) q, q+ p
apiVersion: v1
7 ]# i, q' n: \; P) e6 [2 qkind: ServiceAccount
: Y; w1 m: \! G6 v; a% I, Mmetadata:( q8 |3 O) ^- |3 {
name: coredns+ U8 W$ P4 N5 S I$ d4 G
namespace: kube-system
1 `0 Z+ U6 y: S! i labels:
5 @/ E% R& O+ H) V! R: c. Q* `+ ] kubernetes.io/cluster-service: "true"7 F! k- F) C- o: q' @1 _; i4 ?. u
addonmanager.kubernetes.io/mode: Reconcile# Y; S+ G; H7 j6 E* Q
---
2 B7 t2 o/ V0 h8 X2 { ZapiVersion: rbac.authorization.k8s.io/v17 F9 J& V5 F' U+ }( c+ d, z, z. h6 A
kind: ClusterRole6 B. l% L! D* K% c- ?# O
metadata:" T- O, Q0 r A& T% E
labels:
1 U+ f X" }% s kubernetes.io/bootstrapping: rbac-defaults) P6 o: l3 B3 f: d1 r" ~
addonmanager.kubernetes.io/mode: Reconcile) T r0 u+ r( D9 A4 K: @
name: system:coredns5 b9 z3 v3 U3 g- L/ g" ?0 q
rules:( f5 H. T: m: U
- apiGroups:
1 ^) O6 a: _5 r - "" x$ R9 W5 z' R$ f* f4 f7 }6 v- ^( D
resources:& r2 N- J/ }3 m* Y5 N0 `6 B$ U
- endpoints6 e0 H5 ?# M7 x' V& Y d, ?; W' G0 V
- services; M7 ]1 Y! h Y. H# s$ c8 O
- pods
( ?) }0 C! _8 F3 M- s% p4 `# _) I1 P - namespaces4 c+ I1 p8 ~, R: g
verbs:
3 Z: Y" A& h! m- ]* H; }- _- m) y- } - list
2 I; Z3 F* M, e2 y - watch% c: Y# C" z/ } G! L
- apiGroups:7 i- ?$ K; o+ v4 c
- ""
+ g- O2 ?3 h* s. Z) l1 W resources:5 o6 O! [; r0 {9 B+ a: w, Q7 a' ~! \
- nodes
7 T* n5 Q$ y- X2 z+ H7 E2 v8 G verbs:
9 A- X, R9 s2 H+ e - get0 ~1 v) _6 S7 ^- V4 |1 L6 I
- apiGroups:
$ A6 Q- k7 ]4 i5 k - discovery.k8s.io
# G, B" F( @. H( r6 W! K' W) ] resources:8 y- l: x( ~; {! Z0 E+ x# e
- endpointslices
9 Q4 n( u% L# ]5 z! V verbs:. \0 b7 n! X5 D8 V* r/ \$ D: O) |
- list# h4 b8 h* @ X/ }1 C( {7 \0 X- ^
- watch" _- @0 g7 Z* x' t; Z9 D
---
S: H$ b6 }# g3 X) ^apiVersion: rbac.authorization.k8s.io/v1
# ], {) T! _3 s- s& qkind: ClusterRoleBinding
0 Y" Y4 t y$ [2 _ @0 w" }" Vmetadata:
8 y1 J9 h- _' f: C. G: D annotations:
8 X5 y6 T. X2 M0 F F) j3 _" j rbac.authorization.kubernetes.io/autoupdate: "true"
; x% t9 G6 w2 K% D3 j; X4 S# {2 { labels:5 ]6 w* r/ j3 C1 N
kubernetes.io/bootstrapping: rbac-defaults
% q% n) G+ h2 \" q% l: |: n addonmanager.kubernetes.io/mode: EnsureExists& C; f- D+ V4 |; n
name: system:coredns
+ u! p; |$ h( p% V2 |6 |4 ] VroleRef:
0 ]: M$ u& K( \$ ^3 Z% n; k apiGroup: rbac.authorization.k8s.io
) c" y# j& A0 X' f kind: ClusterRole. }4 E8 T! U6 |3 E# B' t
name: system:coredns- I1 @2 F+ Q; A0 W
subjects:8 g' |6 |* v3 e. c+ x) o" \0 b
- kind: ServiceAccount
7 r/ k, q6 _ s- ]* T name: coredns
T& I) R3 ~! M' Y$ }. g namespace: kube-system
1 J3 {" q* j( y) \; x) D6 t) v9 F) [/ @4 o---5 h/ g+ B) {+ c4 ?3 ]2 X$ P
apiVersion: v1
3 P0 r2 f1 G( d k' Skind: ConfigMap% _' ^- z# s& q- F+ m9 Q+ A6 m
metadata:
' x2 Z: A$ W% n name: coredns; ?/ X+ j, G( C0 j, F2 |' W! N
namespace: kube-system A3 I3 h e5 f1 l2 q
labels:. W6 e+ }1 a* E& C1 |& n2 o
addonmanager.kubernetes.io/mode: EnsureExists+ q1 m- m! g$ w5 I2 g0 E
data:3 a" R/ C; l9 o
Corefile: |
0 l/ c5 J+ ~% Q .:53 {
3 x: @8 o2 n9 V/ c3 j errors
$ L0 V. ]4 X5 U! o health {
! T( f% a, g& V% u& v* C lameduck 5s
- d1 `# v' n1 s/ ^ }! S5 Z$ h) O" f* S+ w, Y0 Q' n1 L
ready* R0 V7 a1 S% [% X: R" X
kubernetes cluster.local in-addr.arpa ip6.arpa {8 g! u7 w# I l- l6 j, Y3 x
pods insecure6 I# }7 ~8 h5 u
fallthrough in-addr.arpa ip6.arpa( K3 Y. v% h) e& C
ttl 30+ L. O `& y$ n4 A' H
}, i0 l4 O4 b9 b+ ?
prometheus :91535 s3 ~' K; D$ \, M, q
forward . /etc/resolv.conf {
( |: f- v G p/ Z& l8 t8 j6 Z max_concurrent 1000
, }& ]; c5 T2 Y: n( Q }
! L4 h: A4 O6 |9 n cache 30( B' E# l& ^8 R" N* |/ `$ m
reload
0 o9 ]. j) {0 J5 Q7 e0 I4 m. A' j loadbalance
& X6 y$ c* H/ O" {. k( x3 A+ I }$ J1 O+ |- L7 b8 E0 A+ v$ ^
---6 i' ^0 R/ C5 ~+ C* F+ Q0 N
apiVersion: apps/v12 ^8 Y# ?6 X' X& Y6 {- i1 M
kind: Deployment# h! T& o x' s* z* C$ E% z5 l4 C
metadata:
' _+ B9 ~& G( G name: coredns
. E+ |/ m4 r( L7 M. B! Z. {/ o namespace: kube-system9 s" }' S% A D$ F
labels:, a4 r# V* g0 |1 X
k8s-app: kube-dns+ G5 k. X0 P0 s
kubernetes.io/cluster-service: "true"3 \9 N$ E: r( l M+ E
addonmanager.kubernetes.io/mode: Reconcile9 c2 ^+ Q) L! y- N2 _
kubernetes.io/name: "CoreDNS"
5 c! @- S$ }1 r7 f8 J8 b: ~spec:
# f2 Z4 m2 D3 Z9 U replicas: 1) l! t) q' A& H9 |+ g
strategy:
( |! p$ ^2 o2 v" u type: RollingUpdate
, S7 C* x0 ^$ X3 ^/ G5 W+ f rollingUpdate:
$ @2 Q# |; a/ o' N2 H maxUnavailable: 19 q% k. l0 p& d6 d+ Q& L$ F
selector:
5 c( Y/ W8 a/ Y* y2 s matchLabels:
. i, o% Q& `: W+ W# Q k8s-app: kube-dns1 L; H' Q& r$ e$ P
template:% g n$ c/ W% y$ t/ g
metadata:' i9 D1 J+ |4 N2 r0 ?$ K- g3 n
labels:" v8 D8 w8 l0 j5 M4 e7 g+ \$ M
k8s-app: kube-dns
: a7 J, \* Z7 {% z c: e# I spec:
9 e# |( s5 {7 Z5 w- J6 s2 W securityContext:
0 U! ]0 g; \7 {- v) p1 a/ L seccompProfile:' [; m' ]" v- d) L7 i* O
type: RuntimeDefault
" c3 Q" U2 V$ b" L8 s priorityClassName: system-cluster-critical; @2 `9 d- q; ?9 p: O
serviceAccountName: coredns
5 _5 T6 h9 w' ^. f* @0 A9 ? affinity:( l: a( T: Q# `/ U3 S) G4 a
podAntiAffinity:
0 U( S+ [ b# E6 Z1 n: h preferredDuringSchedulingIgnoredDuringExecution:
& o! G+ Q; r: C2 F& ] - weight: 100
2 ^3 B0 P% l, Y( f podAffinityTerm:
; e' l% j: I2 z7 \: {+ w2 T8 L labelSelector:
; n" a* d. q7 j* i8 x matchExpressions:2 Z1 E; C' J- p; i; b
- key: k8s-app
5 t- m0 H: ?- r operator: In
# \/ G9 W6 a, |5 m1 O* } values: ["kube-dns"]
, v! A# Y: a: O. s$ }. l* X; Y topologyKey: kubernetes.io/hostname
! h* @: T, U4 q tolerations:4 f6 @$ P2 M" r) l( ^: k6 @
- key: "CriticalAddonsOnly"+ f, }! F# v' I9 Z' t' Q: X* {
operator: "Exists"
# C9 ]3 y0 Y; m" {% R nodeSelector:
5 l. D/ ]; \1 g. i- ]" q kubernetes.io/os: linux
& P( S' u8 c) z" L- L; f containers:$ b4 u# r" w! e# e
- name: coredns$ R( ^) c- o4 L" G0 e7 I* K
image: docker.io/coredns/coredns:1.8.6
3 m+ m, Y7 |3 y7 v imagePullPolicy: IfNotPresent
# j: F' R/ y- R! Q" |) } resources:; {9 |- a1 A0 s, H- J+ _
limits:
, @. e" j" c4 y# e- s9 N memory: 300Mi
; `1 u' n* i$ l requests:: U9 ?6 _" O4 m" G$ c! q& H
cpu: 100m9 G* |% }* k: ~
memory: 70Mi
/ K1 Q; _: v* v( z+ [1 o args: [ "-conf", "/etc/coredns/Corefile" ]5 j, T0 a. {4 M
volumeMounts:
' }9 x; M0 `" K' w - name: config-volume
4 C. t$ F2 f0 n! b+ Z2 H# r mountPath: /etc/coredns9 B$ q6 p R% I6 k
readOnly: true8 d: J4 Q0 t* @- l+ y2 H% f
ports:& Y& S: V T# |/ M9 A: S; A N; Q
- containerPort: 53
/ o( ? ?. Y" A$ D2 S' Q j name: dns: ~$ h3 g! F: G. F) c
protocol: UDP& D' |# [; j! t
- containerPort: 53/ J% ]; p7 X1 U6 C
name: dns-tcp' E1 U! L# X) x* \; \
protocol: TCP* ] K; x4 R& \5 Y. K
- containerPort: 91538 t' U0 S- ?" q% s: N
name: metrics
, E- `5 q8 @8 u4 ~ protocol: TCP! C5 G4 V6 d' z& j& z% U: s6 \
livenessProbe:1 i6 X5 |8 t: u
httpGet:1 G* Q/ e( X- ^6 h; d
path: /health
8 O6 L9 K, x7 f% p port: 8080! `# t4 N" g, R F) p1 k
scheme: HTTP
8 R9 |) g/ a1 _& U$ c initialDelaySeconds: 60
3 E1 i% D+ {6 t `* X timeoutSeconds: 59 Z6 n! L% w! `/ H( q( m- O/ W H7 n
successThreshold: 1. \, c% ^9 w: a. U; ?8 K: ^
failureThreshold: 57 o6 _( i J$ L1 P) A/ u0 ]/ x8 d8 e
readinessProbe:
, e' [6 }5 ^* A3 y$ w httpGet:8 ^- G* b2 J! H9 g9 J
path: /ready
! y' C1 ? d/ Z9 W3 d8 S* H, U port: 8181# c, O& \! B6 H3 d7 N
scheme: HTTP4 [. T/ p9 U% l4 h4 W, `) r# n& c% n
securityContext:! X1 {( F. u% P6 n! k( r
allowPrivilegeEscalation: false
* P' l, a. i) t0 \7 M capabilities:% i. A1 K6 Z; i6 a( G, j
add:2 Z, o, b3 _: Z6 G5 q( @6 A5 t x
- NET_BIND_SERVICE% k5 J- A9 f5 ]- j1 D
drop:! k6 Q( b3 u, U# _1 O4 w
- all
* ^9 q# A$ v3 D! Z3 N. M readOnlyRootFilesystem: true& D8 Y8 t! k7 O& s% z q/ s8 z
dnsPolicy: Default4 h" `1 R7 E$ o% G# o
volumes:( T1 o# i8 m- O& q
- name: config-volume
- l' S1 B2 Z: n. f configMap:
& |2 X e( J- I, m- w) B name: coredns
$ r) d) | S6 c5 R& H1 ~# ?9 d items:, x4 e: O4 _+ K% s3 Y3 f$ f
- key: Corefile
) ^9 Q" U& A3 s# o5 `. X path: Corefile
: T4 w6 Y; O# y# A8 f---7 K7 r& j" {( O2 ]0 Y$ ~
apiVersion: v18 G7 Q c; }9 f B* j# Y
kind: Service
6 U+ r: c* }) h3 lmetadata:5 z, ^4 \4 B# [- \3 C G! m
name: kube-dns4 _# a6 D0 g `+ x9 y5 k
namespace: kube-system
! A2 g* S) p1 C7 K; I5 | annotations:6 u$ }" n& p4 c8 e! l
prometheus.io/port: "9153"
- r6 I! B( ^8 t6 @2 {/ [. {; {, t) { prometheus.io/scrape: "true"1 t6 z( O2 w, i2 U \1 ]& P7 f
labels:
2 p# l' o _5 I8 M7 B k8s-app: kube-dns( |6 O( I1 Q J/ z) }: c$ z
kubernetes.io/cluster-service: "true"
+ U2 X( D: O5 P0 @+ J6 G4 t, z- y addonmanager.kubernetes.io/mode: Reconcile5 R0 T( T* z3 z8 _/ T/ i, a
kubernetes.io/name: "CoreDNS"
. N" }& a1 L& k6 k# E1 Zspec:
( Q7 }5 E9 g. ^4 l selector:6 ~; V; u( x& x% U4 f
k8s-app: kube-dns% n9 a8 `& }+ P- ~+ Z
clusterIP: 10.88.0.20 l) b$ q$ f `8 f$ X
ports:
' v7 l! \6 o# A- A) N' @3 p5 h k - name: dns( D8 h" j J$ Q* b/ x) u& K
port: 531 m3 T2 E# U3 f6 |1 u
protocol: UDP. y; W+ S9 d2 e2 g) W9 _2 W1 i
- name: dns-tcp
) q. w9 J" ]# X; C( p8 l port: 53, D8 N$ d" |$ {& l8 I p, N! z3 R& g( h
protocol: TCP$ u f8 V: X) E' Y$ r
- name: metrics
. \$ H7 b) T) G( G+ z# ^ port: 9153
D, k: Q9 B5 j3 W# K' r5 L protocol: TCP0 G q! u, \( J+ j2 d8 Z+ R
导入 coredns 镜像
4 G# x- X7 [1 ?( p8 o7 u! z% L v7 nfor i in 192.168.91.19 192.168.91.20;do \7 H. c# x5 y- y, O- s4 H" s2 ?
scp /approot1/k8s/images/coredns-v1.8.6.tar $i:/tmp/
% K4 t6 M& ~ essh $i "ctr -n=k8s.io image import /tmp/coredns-v1.8.6.tar && rm -f /tmp/coredns-v1.8.6.tar"; \+ ~# |9 p7 ?/ d2 n; A/ i9 j
done8 t3 b1 o5 W. U
查看镜像
( m% J3 X7 [) n4 A- k. I9 B+ J: v+ C U" V
for i in 192.168.91.19 192.168.91.20;do \
5 U4 @4 \; w) w) {% W6 qssh $i "ctr -n=k8s.io image list | grep coredns"; \
0 h( m5 E& W# w! T/ Ndone1 i6 A; x- h5 n$ S: q) [4 o
在 k8s 中运行 coredns 组件
$ F8 p' L* t/ hkubectl apply -f /approot1/k8s/tmp/service/coredns.yaml
/ t( e( J5 F7 w% }( h7 ~* ^检查 coredns pod 是否运行成功
; w* I) ^) O* ?1 B+ Ukubectl get pod -n kube-system | grep coredns9 T: _- q. z- Y: ~0 j' V( g
预期输出类似如下结果
* y+ O$ L! E# S& L! E
/ v" |5 {( a; Z& |3 h因为 coredns yaml 文件内的 replicas 参数是 1 ,因此这里只有一个 pod ,如果改成 2 ,就会出现两个 pod( x; h3 N2 E/ |* h0 f
% B7 E! A+ D- u. h( K
coredns-5fd74ff788-cddqf 1/1 Running 0 10s
9 g, W2 K R; m- k$ h3 [/ ^$ H' L部署 metrics-server 组件" s1 F8 g5 C, j8 y( M% k& ~- W
配置 metrics-server yaml 文件
1 T( {1 g% [3 w: p- H7 M1 V+ Cvim /approot1/k8s/tmp/service/metrics-server.yaml/ Q: I$ O2 b N/ W8 Y% p& @
apiVersion: v1( Q1 _8 I1 \2 S8 G8 l
kind: ServiceAccount# s0 o4 \- K6 ^! A0 j; e L
metadata:
/ e, [3 C# [$ i1 K% B' K labels:. ]8 h2 c+ b. _& }
k8s-app: metrics-server
& _7 C9 \* b- z name: metrics-server
4 r- j+ k1 B6 |, @' T& m( \1 [ namespace: kube-system
9 Y5 q9 ?: n- k1 J, G* u4 ]7 k---5 e/ y S9 {( J+ E$ \3 x3 ]
apiVersion: rbac.authorization.k8s.io/v1
; t! h+ J& C8 O% F9 l* |kind: ClusterRole, q) X; X7 w# ^, ?$ N) ^; p- L* E4 F
metadata:) D ?& Q/ C) M4 G2 I% ~& }: K6 I
labels:) j1 W/ h) U& H
k8s-app: metrics-server
/ M, t2 M' b4 |! I# Z: n1 v7 a rbac.authorization.k8s.io/aggregate-to-admin: "true"( ?, ~& g, x6 J3 @' c4 k8 _
rbac.authorization.k8s.io/aggregate-to-edit: "true"0 ~/ ^; U+ B3 I4 t$ g; D$ i
rbac.authorization.k8s.io/aggregate-to-view: "true"3 u- X) ]" f- Y0 F- C% t. N; F+ V
name: system:aggregated-metrics-reader8 D* Y) d2 I) v) F
rules:
1 D" d! f& g+ D; G' z8 l4 G$ U- apiGroups:
) y# ^- H9 V1 i1 A% M; d8 X - metrics.k8s.io
7 N' i$ b- T* ~2 q( v8 H resources:* K( T$ d4 \- }& k+ \
- pods
( h5 P, H1 a- M% |' x' L& N - nodes
4 w0 J/ G0 V$ n' D& | verbs:
5 g2 `0 R* C* \ - get2 J2 _" l* r' r( v& d
- list
1 L+ m; b: R# o, f9 t* U7 @$ Y! }1 F, J - watch
, ?' l/ \4 Z& Y: P n, U---
1 B# ^" U- ~* |% B2 japiVersion: rbac.authorization.k8s.io/v1
$ y) U/ R, W0 W4 e- Kkind: ClusterRole7 k: n5 B ?1 p* @0 E% W
metadata:% j7 C' y. v$ D5 P
labels:. U* B5 ~ E+ G
k8s-app: metrics-server2 H$ P) j- D) P' f6 j( B! _
name: system:metrics-server
8 a1 r: Q. d1 o" Qrules:
* n5 K1 }' Y+ A# F- apiGroups:
7 I' C; y) Z/ L$ c7 N; f - ""! S: }* N; m- w9 E4 t5 N+ A
resources:4 n: ]/ S5 \) j: _$ E
- pods" N8 g# h |7 M- F
- nodes
. g, c. \ D3 ~ z. S! ^8 G6 Q8 p. e - nodes/stats$ b) I# Z. p4 z. `5 t6 g
- namespaces( W* W" \' Y5 J. b* u
- configmaps+ c: c6 E' M# ?9 j4 U3 m$ i$ e
verbs:8 ?1 N5 [8 s" h) @0 N" v
- get
' Z2 Y# G; X; W! I0 ]0 ^ - list
; I' n8 g1 n. Z - watch
' C0 t" I. Z$ \+ ~. P4 Q---
6 {6 W+ ^+ g2 T" z: w' i8 S2 QapiVersion: rbac.authorization.k8s.io/v1
* S) [0 A. N4 ]kind: RoleBinding! i' _* f) B9 u; C* J- {* h
metadata:9 s& |9 X& l: B' r6 |$ O2 C8 Z2 H2 M
labels:
& [# G2 S1 n" w0 j k8s-app: metrics-server& e$ v! C" ?' W+ P, D! A) k
name: metrics-server-auth-reader
2 o. y3 @5 n1 I) ]% n* _5 Y4 ` namespace: kube-system
9 h1 P! [: T7 B- T) Z" wroleRef:
, D: S' r" a1 U apiGroup: rbac.authorization.k8s.io6 L) z, G( l# |: K! p2 W2 y t
kind: Role
0 f; y& {$ Y) M+ S& n0 Q y name: extension-apiserver-authentication-reader
2 g( P2 A. z8 p, tsubjects:2 n( B9 w% N5 f n8 q9 D
- kind: ServiceAccount3 k/ z" D" `, ]
name: metrics-server
+ k0 R. H4 [9 q3 G7 j- z" | j4 n namespace: kube-system
1 U5 N+ f3 i7 j$ k2 K---
4 w4 t9 W6 a9 }$ B. d {9 V! HapiVersion: rbac.authorization.k8s.io/v1
( r) J X' m: G1 `% `3 V/ gkind: ClusterRoleBinding# O; D+ L# y- o8 ~, S- e0 Y: ?9 N
metadata:* u0 [# p6 ?# d& E
labels:
% ^4 U& R! e2 I5 U k8s-app: metrics-server, A" F3 J; a" o! @
name: metrics-server:system:auth-delegator
* K* ~* u+ ~, y* [& N7 M8 L. ^roleRef:0 ~6 H4 e; C9 y# D% x X
apiGroup: rbac.authorization.k8s.io. }) a* f" m8 `9 c: O5 u2 c+ X% n8 k
kind: ClusterRole
$ L8 W- X2 O/ e& P4 ? name: system:auth-delegator- G* N. Q( I% a0 p9 m
subjects:% s, c7 }; \% M! e8 s2 i/ N
- kind: ServiceAccount
. [/ ?, n4 V1 }! ~" \ name: metrics-server' v- w. {/ f- C' Z; H* m0 P( ]6 S# h
namespace: kube-system
. {" y r1 |7 c1 Y/ l---
& T8 u/ F& }% e% z* JapiVersion: rbac.authorization.k8s.io/v1
8 |4 Z$ ^# G7 r. @) }( Okind: ClusterRoleBinding
) N0 i( B! f6 Jmetadata:. d+ a* Y' o/ I# u- |6 s. {
labels:
0 x T$ v% z2 t) h& ]9 Q( u* t e* P k8s-app: metrics-server
" L. z1 a4 E( w9 ^! t name: system:metrics-server/ c5 p: y Y6 Y' ]# H8 @7 n
roleRef:
* j- z2 J% ^4 E- s% P& T# L* b apiGroup: rbac.authorization.k8s.io/ f: {4 p$ }$ N1 A f9 @. S% n
kind: ClusterRole
# b9 v. G, d) c) A1 i( u name: system:metrics-server7 t% J6 M. ?' h5 l% E* x8 U
subjects:. M8 _1 ], e4 y6 ]
- kind: ServiceAccount
/ A' a* y7 {6 A; Z9 B' a7 N name: metrics-server
! ~3 ~1 b, U/ R namespace: kube-system8 q+ @8 D( }& a% W- N
---* n% K8 G& ~5 A: E+ g7 o
apiVersion: v1/ G: h/ F( V/ m& _
kind: Service% {8 G* A8 l) D3 W+ t* |9 q
metadata:7 X. f: W( d9 g' v8 y; ?
labels:! [2 v0 \( l+ f6 I& H& ?: J
k8s-app: metrics-server
" B& G# x/ j1 U0 Q( v0 t name: metrics-server
) Z1 z8 r7 k* o' a namespace: kube-system9 V1 [/ g" H, H% B5 a) ~8 c) l5 Z
spec:
) X( \% B o' H ?! R5 v ports:" ?; S+ @( ?. R; W: g. W% M+ X
- name: https
5 T0 ~5 C6 @4 q6 h3 h; z2 c n port: 443) X# w: @' o! X6 Z# n8 b
protocol: TCP1 D: T: w& t: p+ P. R9 ?8 q" X
targetPort: https
: Z) P+ J. i( x0 w# Q9 A& E W* ?% _ selector:) P2 L1 h" a* V
k8s-app: metrics-server) v+ O% k; J, G. Q% g. H e+ T
---! h9 W/ Y) D K, H$ i
apiVersion: apps/v1
/ }5 V9 d) K1 ckind: Deployment9 W$ c9 W: t4 {: f
metadata:
& x# N5 K7 i- L labels:. f& j% o/ o1 k: T; Q- |. l5 ]8 f
k8s-app: metrics-server- L( _& e# @, i. B0 A: }
name: metrics-server
3 F& U) M9 F4 V o2 i9 k namespace: kube-system& o/ ~/ @: K6 g. }+ K( }; L y
spec:
/ `! G' {! \( J, r selector:& r- q4 c0 y! F/ P/ e
matchLabels: b) S& l% K! \$ U% g& h) v* C
k8s-app: metrics-server
- }) @; V! ^/ w2 n strategy:
. W: g6 z) S- A# T8 m- A rollingUpdate:/ k0 C: B# ]' s
maxUnavailable: 0
! u# P8 e7 u# O' b% s2 }- D template:
: }8 l; x& a. n8 S) y metadata:) j. L+ N% {1 k$ w
labels:
, a7 C+ K$ v7 I) c k8s-app: metrics-server
% s. C5 m# E9 _' K! M spec:
" g, J* ~+ V4 {; I" P containers:
& `% m& z1 w8 H- p$ f - args:
0 M+ s: j% \3 q! D8 h/ O - --cert-dir=/tmp$ H- d) W: G) k$ M: T5 i' t' N u
- --secure-port=4443
2 n) ^$ D: ~; K/ V - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname' E3 ?7 q% J# \2 ?7 w, }3 a
- --kubelet-insecure-tls
' y; o+ o$ \+ _1 T2 f5 @6 V' r - --kubelet-use-node-status-port8 I! j0 C: `* u( R/ i8 Q: X
- --metric-resolution=15s, Y1 [; G4 @( f
image: k8s.gcr.io/metrics-server/metrics-server:v0.5.2/ m2 m9 F$ R# K3 k4 r
imagePullPolicy: IfNotPresent
9 c( L5 {# C: M1 G" C' V3 V livenessProbe:4 K7 O. W; o1 j( U) h: V
failureThreshold: 3
7 Z: I3 Z/ O! m) P7 }- h httpGet:
2 e U. n7 v- S# U9 }3 t9 E path: /livez
P6 }: k S) j" M d! P port: https \2 Y; }+ k, a2 g. T, x
scheme: HTTPS+ M" t7 J/ M1 {* Q" ]8 T
periodSeconds: 10
. k2 t, |" e! K name: metrics-server: O* i0 O0 P# H: v3 a( f
ports:
; i. A8 ~3 X4 O# E5 |% i, M - containerPort: 4443! N1 O, D) `) r- d& x
name: https
{6 H# f# }. ~' u! } protocol: TCP: d/ h, m1 B6 ^; i& |7 E2 W! @
readinessProbe:; y& P _9 ~: f
failureThreshold: 3, G% t1 L8 P! H9 x$ d' D0 e4 e4 ^
httpGet:6 |. N+ q" t. T* Y
path: /readyz
- p7 W: J9 @; r9 g; F port: https! h! n; K; y" h. R! Z5 J7 I
scheme: HTTPS3 C n( R3 @4 j2 _8 y, W
initialDelaySeconds: 20
# u1 l; w3 Y5 E3 \- o periodSeconds: 10* E5 n3 S5 S9 b4 c; L
resources:
& M% j9 b E5 S: G/ r7 g. R requests:
, Z+ L U! ?$ U* U. X( f cpu: 100m
) a3 D' |' F4 K9 V! Z memory: 200Mi
: Q! Q. w- w+ ?/ A f5 r4 @ securityContext:, v1 h& h/ \# S- {
readOnlyRootFilesystem: true
7 h7 e" Y0 {5 y; S2 v runAsNonRoot: true4 f* O, o- P8 b/ k
runAsUser: 10003 }, _! W9 E& X; W
volumeMounts:
3 o9 f, j8 X8 Y; x; L - mountPath: /tmp
. d$ h5 L j3 n! i" o9 q name: tmp-dir
; l3 D6 ]/ E4 I nodeSelector:0 U* B6 D3 d2 h' p# {9 R, P
kubernetes.io/os: linux
. h. ?# _/ T6 d: l; s* }0 z _& c C7 } priorityClassName: system-cluster-critical
4 z7 V {' t$ e serviceAccountName: metrics-server
% t, h6 H4 u# ?, F# ] volumes:, O e9 d) W4 D: q3 D; N
- emptyDir: {}6 A* G, x6 {6 w0 }) D# A
name: tmp-dir
. `/ B* c) z0 o4 F6 K3 C---- S8 o* P" t+ f5 d: L' @) m4 q# c
apiVersion: apiregistration.k8s.io/v1
! P, L+ j9 }! r; h2 j' Fkind: APIService
7 f5 q% M3 L0 P wmetadata:
/ a! u& t( Q' q- n$ J6 k# D+ ]1 x labels:/ K" F' x. @% [6 _
k8s-app: metrics-server
# {, _- S$ b. }0 @ name: v1beta1.metrics.k8s.io; d2 A4 r: \5 }* K% S% I1 w* R
spec:
, Z9 K: A, O7 c9 J( `' B group: metrics.k8s.io
5 D* a# g( ]0 T* ?# x7 l7 p( k+ J groupPriorityMinimum: 100- }3 ]3 P- u% J" U P& X
insecureSkipTLSVerify: true
2 p. t+ W) E8 L, N$ D2 d1 \+ T service:1 l* u0 c+ S9 E" {# C w+ r0 j, W S/ e
name: metrics-server, G" y9 [" W* N
namespace: kube-system' }& m9 O; L' n$ R. r
version: v1beta15 v! }* n% @1 h9 R
versionPriority: 1006 u2 w( Q1 [8 F4 ]# Z- x- z
导入 metrics-server 镜像
% b2 U& i* X# {6 j8 _" hfor i in 192.168.91.19 192.168.91.20;do \
* j$ S s" o8 _# Zscp /approot1/k8s/images/metrics-server-v0.5.2.tar $i:/tmp/ z6 p8 s ^7 ]( ]' K
ssh $i "ctr -n=k8s.io image import /tmp/metrics-server-v0.5.2.tar && rm -f /tmp/metrics-server-v0.5.2.tar"; \
( O7 a# K- i, a% o6 o, h$ ydone
1 E7 q+ m; k3 V9 g" W9 z& J查看镜像4 O0 |% L/ C' M7 z' p. U3 ^5 I) h
2 P+ B$ m q) O1 Mfor i in 192.168.91.19 192.168.91.20;do \! R& }3 k# K2 G, a- i$ E
ssh $i "ctr -n=k8s.io image list | grep metrics-server"; \
5 H! E2 c6 n8 S5 ~6 x i7 [5 N4 n9 }done0 K" I6 \( B, d3 s7 @
在 k8s 中运行 metrics-server 组件
- u7 Y8 K7 Q8 t# a& o kkubectl apply -f /approot1/k8s/tmp/service/metrics-server.yaml
' Y) W) L' I, p" T检查 metrics-server pod 是否运行成功
9 l4 q' }$ A( t6 I8 V) _kubectl get pod -n kube-system | grep metrics-server
2 H1 k$ u8 N* }; D" |预期输出类似如下结果+ s1 V9 z- z7 v! t6 m
( Q5 e! p* Y! |; R
metrics-server-6c95598969-qnc76 1/1 Running 0 71s. p% r: S7 g; `
验证 metrics-server 功能0 U8 n* `/ g* z3 G1 x
& E* J6 M5 M8 i: ]+ a$ i- o! b- ^- [2 _+ r
查看节点资源使用情况& z5 Z) G J( J7 v
1 C- Z2 `- S2 {$ J3 xkubectl top node3 A& N0 B6 f7 g" M: x
预期输出类似如下结果# T" P" ~" W" D6 G. }
% \8 G' j7 m4 U: E6 `1 K! v) `3 Fmetrics-server 启动会偏慢,速度取决于机器配置,如果输出 is not yet 或者 is not ready 就等一会再执行一次 kubectl top node
% R; R) b0 Y! u. X- s Q' d0 h( M
* P2 m' {& N4 |& ^3 S# E. _NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% h& s: M9 L- ^9 C
192.168.91.19 285m 4% 2513Mi 32% O, w$ J" z3 ^8 Q
192.168.91.20 71m 3% 792Mi 21%
6 I7 x. ]- x( }# \; g查看指定 namespace 的 pod 资源使用情况% U" z7 e$ j. ]* |& E9 C
8 M- J- \1 |2 i) {kubectl top pod -n kube-system' M" ~" E( t9 F4 T m
预期输出类似如下结果
: X% X9 b6 s7 {7 w9 E2 g2 R3 z' z" ~
NAME CPU(cores) MEMORY(bytes)
# I6 t4 p% ], P5 zcoredns-5fd74ff788-cddqf 11m 18Mi
E, `+ o- _2 @% ?9 l4 F z+ akube-flannel-ds-86rrv 4m 18Mi+ H2 l w3 z+ v: z
kube-flannel-ds-bkgzx 6m 22Mi
% R5 d1 ^1 E4 B& kkube-flannel-ds-v25xc 6m 22Mi; s D% X' |7 {6 ^2 ?6 w
metrics-server-6c95598969-qnc76 6m 22Mi' h9 b( L0 T3 F" [/ I. b
部署 dashboard 组件 x g; Y6 Q9 k/ t- Q4 V1 P
配置 dashboard yaml 文件
, @- r3 d! p+ h- X6 P, Mvim /approot1/k8s/tmp/service/dashboard.yaml+ J0 p, P9 p7 f
---
3 h& e* F; z& n0 b, dapiVersion: v1
E$ `- b% e! H0 H; Pkind: ServiceAccount8 j" P( }& X9 ]) d
metadata:/ v a6 Q/ T# y
name: admin-user& m; a& F* N0 }8 s0 u9 {/ Q. H6 d
namespace: kube-system3 e3 A% {9 h5 n8 u' f0 u+ d
" ]# t1 X# `" A. J( F( k. O3 \/ [---
5 f& [( F8 R, |$ O) F1 g* KapiVersion: rbac.authorization.k8s.io/v1
( U9 j- O' S0 f2 N4 C- bkind: ClusterRoleBinding# G$ w2 a( V) E, c" A+ G
metadata:6 ?! w& x3 T1 N* A" Q# Y
name: admin-user4 ]3 k4 ~+ M5 Y4 Y# K
roleRef:
$ K- c9 ~# o$ c7 [& B1 W apiGroup: rbac.authorization.k8s.io
' I/ b# S9 w+ i( W1 B% ? kind: ClusterRole ~1 B% t |* Q9 V3 I
name: cluster-admin2 D/ H3 f2 w9 U
subjects:
5 Z% y8 n) Y m# j- kind: ServiceAccount
, a0 u! d3 K& B- U v1 V name: admin-user
4 `5 `# [1 M1 z1 { namespace: kube-system
( l+ r; B, i y8 H3 q% n9 _% k6 X" U( n/ w
---
1 l8 |" {( ?* v/ X9 G$ O( vapiVersion: v1
: N7 W; _: E+ `8 Okind: ServiceAccount
( g0 K& J" r: p% R) w: i+ umetadata:
5 Z9 E7 X+ A1 R name: dashboard-read-user
5 U- s3 z* Z& Z( d' V8 n" p namespace: kube-system) s/ I* }* ~) t3 u% N& B/ g
* I' p+ O6 O" h7 X0 t6 O: |. l
---/ F6 w" W8 T5 |
apiVersion: rbac.authorization.k8s.io/v15 R: @9 d5 A1 ~) z4 b+ |
kind: ClusterRoleBinding
, ?' U6 |. B6 V* j& b: I$ Kmetadata:7 P& d: I- C7 c/ B" T
name: dashboard-read-binding% }& h6 r/ `6 R! g7 l
roleRef:8 X D7 j1 B' G3 P
apiGroup: rbac.authorization.k8s.io
k8 v) w" z) R kind: ClusterRole" f I G% l8 R
name: dashboard-read-clusterrole
4 n" q0 Z7 n. o6 k9 w# u( Esubjects:. F) R% F0 X6 z/ ~' j) c+ F
- kind: ServiceAccount
; w) S- L- l8 T6 u- E: j name: dashboard-read-user. v* I; o! c+ |5 J) ~3 q4 u
namespace: kube-system
) A; P9 U0 ?, m3 ~& d e4 l& q" w8 O E
---
/ j& V& w- m( C/ z7 d/ d5 vapiVersion: rbac.authorization.k8s.io/v1
" l8 G; j: L: ^: |8 Y) Hkind: ClusterRole( ]4 V( K3 J: V. Y
metadata:
$ R/ l: T- @, C h3 F" Z5 U name: dashboard-read-clusterrole
( a2 j1 B0 T Z, P* c/ nrules:+ P$ @3 C! H: ^" U+ g
- apiGroups:
2 a: |! I2 P7 z' O: c - ""
; d1 F8 Y0 i: C# X resources:
: Q2 z! W/ j) E - configmaps6 F7 u+ g. Q. ~, J
- endpoints! r5 O( X: n$ c" c
- nodes7 G8 t' A- Z( B# t: C: F: W
- persistentvolumes2 {/ }2 O) L2 `4 i8 A1 J
- persistentvolumeclaims
% h K- Z1 W+ j8 \$ y1 p - persistentvolumeclaims/status
p* M* E/ {0 G% [6 Y: p# K( D - pods
/ L6 V' I) W, {2 }/ F$ [1 z0 e/ c - replicationcontrollers
* |7 \- d4 ^$ r- E - replicationcontrollers/scale
: y* y( Z, `# {( s- n4 [3 T; f - serviceaccounts
, G, X7 `) g; ?: ]# p7 [$ M$ f - services
1 ~; |( k' S% l. m! l - services/status0 V$ m) w }+ w3 O
verbs:
$ Z1 R2 p' S, o. w$ N. n, G6 l - get: Q0 O, K& i: A8 V+ q
- list0 A, Z l3 }# r1 a6 t$ s
- watch% Y+ f: j. n! W4 }
- apiGroups:
% [/ d. m* A) x6 K' X: Y( K - ""9 p9 |5 n* P: H0 q8 J- Q/ E
resources:0 I2 O& d8 u& x- J! t/ t; `
- bindings
3 | B$ X5 i8 n% U8 M - events- `5 @! u( q( n2 j2 m& y/ p
- limitranges" ? ~0 X* {/ s/ K U, n
- namespaces/status. ^! l6 _# }# T+ @1 _
- pods/log3 k" f& f7 f6 M) O5 p, H
- pods/status
9 R, g5 N5 M/ ~* b7 G6 m6 o - replicationcontrollers/status6 r- H2 t# ~5 T! W$ P& k
- resourcequotas
; [- ]: R r3 O. U - resourcequotas/status6 g4 P( z& h5 I) B" C, C9 ~, I# o
verbs:5 W* I7 V! a; X/ J) ?
- get9 o% \$ c5 |" _( g
- list/ J6 x% G0 ?% p L9 K
- watch
, u3 |: @6 S, J8 Y: A& ]& @1 r; Y+ t; B- apiGroups:
u% C" Q; M7 Q; L0 O5 v: p - ""5 Z/ d {3 o1 B- k; x9 w2 L& ?
resources:
, q7 J; R( o2 B6 v/ v0 J% Q - namespaces- E" ^) y$ m- G7 q: H
verbs:
8 q# O0 r0 i. }( D2 R% x- J - get+ P7 \* d" S' O6 C
- list) Z! B8 i" x! a5 p: O7 U& ]$ K
- watch
1 n1 S3 _3 g+ g w! X( s- apiGroups:: L8 R" Z8 J" @9 {7 S2 h0 a! u0 Z
- apps' f2 \- X; j$ w4 V3 w$ \/ f
resources:
; P% F3 }. [5 { - controllerrevisions
( o6 e* n9 y. d1 X. `# R - daemonsets
4 N) f* F) B/ d7 d - daemonsets/status
( M8 ?: n, b/ J$ W- ]$ _: Q) @ - deployments" A2 n5 d, [, c
- deployments/scale% \" u: O: v! M" I
- deployments/status
, I1 D2 ?. T9 e: o& f - replicasets# [2 O5 k7 X, n+ c: A7 c: _
- replicasets/scale' e; V7 i$ a4 j" o
- replicasets/status
z% w) w- q. E* p% l3 n" J5 A - statefulsets
+ R& e" n* C6 Q F- N - statefulsets/scale) `0 n3 L4 Q3 n$ z5 l
- statefulsets/status
5 i# h9 f5 Y9 `# D; y3 _ verbs:) L4 D+ b# I4 |# n. A! H- s
- get' A3 {8 f. G( _! ^# M/ H
- list
1 g# s& @2 I" B- ]$ w - watch1 T- a8 W! R# E& C7 O: I
- apiGroups:
/ E# @0 b/ u _; Q4 _1 ~ - autoscaling$ k# C1 g3 R2 }& C4 c3 H' c& V
resources:2 H F& \4 b7 U3 x$ s5 O
- horizontalpodautoscalers
+ J3 T: ]- D$ ]6 w% k - horizontalpodautoscalers/status
0 g/ ?) v. U k, t- | verbs:
# v' m7 b: ~0 N! q3 n - get, K+ W* ~& @# t
- list
+ N( H3 p( I) N) c7 _* P - watch& F/ O8 R5 T) l* _* y# P
- apiGroups:6 ?9 A) {( y2 r
- batch& e& P) l! h* r$ T" c3 l
resources:
?1 _6 I" {+ y) y - cronjobs2 X) C6 j- c9 g, b' V9 f: z
- cronjobs/status$ i( q. o ] I$ ?1 B. x3 `* v/ W
- jobs
- E1 F3 p; n6 ?8 M4 h1 S - jobs/status! f2 c; M& [! \$ l1 b
verbs:! |% H% ?8 U F
- get
$ _8 _& \/ h6 g0 V" A% H- |' o - list
4 J$ R6 @7 B5 u8 i( d( c9 P - watch
( h/ @- i; }) Z' l5 \7 M- apiGroups:) I, L7 O6 p3 Y- b; P
- extensions
/ ]9 h% q1 _4 l! [. ]# I ]5 [ resources:) |* P, y: T- Z6 @% Q2 c+ ~9 N
- daemonsets& z1 k5 [1 n4 V: M
- daemonsets/status
. ?: o& J: t9 L* Z- y I - deployments2 ]6 |* p3 D2 }% j6 R
- deployments/scale
) N/ }7 B1 F5 Z4 e, Q9 a- q& C4 Z - deployments/status
/ X8 ~: @( e0 F& n/ o. `$ h7 n$ f - ingresses
4 c R1 s% b7 t: y+ D m - ingresses/status7 O' ~6 D3 b" W0 F4 ~
- replicasets8 L. z& C$ O+ B x
- replicasets/scale
# b& ]' t+ u0 s3 q7 C1 M* U8 y; F - replicasets/status) E3 N" ]8 c% Z9 M: J2 l3 N. @
- replicationcontrollers/scale
- V1 R+ Z8 W! t8 t) r, _/ g+ v verbs:
, o+ ?* X5 S) U: I$ k - get
! d. [* _8 R% B - list
4 V( V! s* k( r0 v9 K: g: @ - watch
5 H1 f. s: U5 h$ h: E' f- apiGroups:
1 S$ l: e1 x* t: J5 _! D - policy
9 E' D2 P0 n9 i* r0 Q8 y' J resources:
' s0 i2 A v, X* P* x& r' g n - poddisruptionbudgets
. m& w; B% k, [ - poddisruptionbudgets/status
' k: n- ]) i3 \7 ^ verbs:
: c! Z# z! I7 k8 R: `! d - get
8 A; j/ M' B* W2 g4 ^0 n" o0 T5 q - list
, _: \/ P. Y- f: @: s9 f8 ~& k. G - watch$ Z9 c( C- g B( M9 H8 n
- apiGroups:7 C8 C8 N" @# t2 V2 L& Z4 T
- networking.k8s.io2 k+ E0 d# ]# W, [% ]$ O% T
resources:
8 z! d" @5 U( q! f7 n; k2 E# F$ k - ingresses
2 Z0 E2 I t0 U; ^& y* W - ingresses/status
' k$ u. r) C8 L8 x; p! Q0 b+ r - networkpolicies `0 R6 ~3 E$ {) I4 ]8 \
verbs:
3 J3 u/ y8 M7 F* w0 c - get/ h+ `$ I' u, J8 C0 L
- list6 B0 S! A4 W2 s; [4 h
- watch
; x2 `; n' O- Q3 _4 @8 m- apiGroups:
3 ~# K5 X! Q( u5 Z$ s/ W5 L! y - storage.k8s.io
6 W1 |+ c* C6 U; j" p resources:2 K1 y% o* Z' c/ P
- storageclasses- g. G3 K0 ?2 ]# X- z6 K
- volumeattachments
* ^0 J1 p* _ d* f# O8 y verbs:8 i5 \" K8 z# U) L$ z% v- f$ a+ t
- get
. b$ ]! Q4 q, }7 F, c - list. B: Q' \, l1 @. m# P# y
- watch
1 q" N) C0 }1 t- apiGroups:3 Y1 f# ]/ w0 |% B! w& N
- rbac.authorization.k8s.io
, U* u9 P+ r$ W8 Z. c resources:
! h D% U0 z8 V7 h! y/ K5 L - clusterrolebindings
! {$ Q/ _- X5 G# ~ - clusterroles
5 J# u( F- x$ o1 ~5 Y - roles
; }# V! h7 h/ |& x$ | - rolebindings7 o4 U$ R& w" q, |
verbs:
0 D) S0 V6 o" F( l/ D8 t/ n6 o" n - get, F, D5 `0 N: w0 q+ b
- list, o. `8 H. o/ |; j4 o5 q" L
- watch* H! e. g) m c- s7 ]$ o: d
8 G0 S1 d9 ~' L& {---. A+ C0 V" a" i9 D- N! P( i
apiVersion: v1) p, [, p- b5 O9 ~
kind: ServiceAccount% V- e8 W* b# \9 z9 q
metadata:
* V5 W1 n) w7 X9 D! k labels:: [" @2 `/ R& @/ m- \$ }4 T5 `
k8s-app: kubernetes-dashboard
; z# l# J& s$ l! ]2 m9 ~% p* F name: kubernetes-dashboard2 ?$ s+ ^1 t- {; p |, E) t) _
namespace: kube-system/ e4 ^' J# e: v! ~' v
& Y t/ D* l/ Y4 f; U b# l
---
: K6 M) H. j3 F& j) ~kind: Service
5 b7 N, }- w- J8 m J$ Z, W% z3 yapiVersion: v1
' L& g; G% t8 W; Q" a" H, tmetadata:
7 Z j, n+ A9 X& t labels:
* {0 w; i4 n [0 o k8s-app: kubernetes-dashboard
- S" y: m, T+ f kubernetes.io/cluster-service: "true"
9 n) p" h: t. w8 S name: kubernetes-dashboard" x. o% g9 V O# q$ Z+ ]
namespace: kube-system
9 N. \2 c; a$ ~ J Bspec:& {8 b+ u: l) X4 |0 W z
ports:" N/ p0 e( d# [6 \
- port: 443/ C1 _! X+ y# I4 R$ I
targetPort: 8443
9 x: L' S+ y: G- U$ C! @* D selector:+ o4 m+ f6 I; ]# o9 t
k8s-app: kubernetes-dashboard
8 e4 {( R$ j% [$ V$ S" S9 t type: NodePort
, d8 d, f4 _* @9 q, y1 s+ K/ t) Y: l$ ]& h8 `3 S5 o
---
# [8 N5 n1 {; _0 ]apiVersion: v1
) | g; m: U( Z, t6 N# nkind: Secret7 M6 Z) L! @$ N+ i. `
metadata:
& s* z2 j9 z! Q* k2 f% { labels:
n- k w- P- b' B k8s-app: kubernetes-dashboard
( u( K( m- a2 Z$ W3 N$ H* I name: kubernetes-dashboard-certs
* {: Z& i1 h; t" r: C namespace: kube-system
5 o) }% B, Z c# `1 e ftype: Opaque1 B5 B) t$ o4 l! C, T7 f
, ?4 \6 a1 Z& V2 ]( }---
/ A- B2 r: Z8 b( K; t4 [7 MapiVersion: v1
4 Y- E; B; y6 e$ u" ~( b% ]0 ekind: Secret
( h5 T! l5 T, s( P5 ~9 {, B4 i' i/ hmetadata:+ g) L& o& W) {, [" S1 u3 I
labels:
N7 F8 m. w1 o* e3 N k8s-app: kubernetes-dashboard" P! h& X5 D2 D7 L" @- m8 O! m! O
name: kubernetes-dashboard-csrf
+ ^% Y5 ^# ^' n# @ namespace: kube-system: u; W3 L: S- x1 n
type: Opaque
; |) M! m( }& M( gdata:3 a: [. x1 ~' K& v9 f3 M1 C
csrf: """ e" m# i; X0 i& E g
/ m0 U( F: t) U
---/ [- I) R0 N0 Q9 S5 M4 {/ _2 M
apiVersion: v1
2 F* {! a# g; E( f8 xkind: Secret
4 O. }6 y, j; x+ Nmetadata:
* Y, d H- P3 ]9 @0 ~ labels:
8 l2 z9 X% J1 R, G0 G: F k8s-app: kubernetes-dashboard2 m( w7 T" @) h6 I
name: kubernetes-dashboard-key-holder$ U# u8 S. ^% X8 b$ m) j9 ?
namespace: kube-system( i6 R1 x1 O, w( T+ t7 q
type: Opaque0 C0 c7 [+ v2 U3 U! e! g
* ^# t$ V. P; S- z }
---7 F/ E/ v( A: N( \2 f2 j P
kind: ConfigMap
: N6 U; D* a) Z0 l. ~/ [7 j/ BapiVersion: v15 J! t# r7 V( F7 J
metadata:
7 M% _) Y1 V5 S$ o6 t; g* F0 | labels:
9 _/ |, O- n! B7 I/ i7 d. h8 d k8s-app: kubernetes-dashboard
8 Y3 L; G ]1 f name: kubernetes-dashboard-settings: x% `- M) k+ G, H
namespace: kube-system
) L0 z7 w: {# s z+ \5 X1 }' x Z8 X k
---
; X$ ?# |# M7 i, Q2 A7 lkind: Role
/ v3 `% V7 f8 }5 o$ H$ I; \apiVersion: rbac.authorization.k8s.io/v1
, T: J+ w! Z& _. c; j: |% B4 u# nmetadata:' h) O2 @. r# g% D% u7 v) g9 H
labels:- P* o0 F) q/ S
k8s-app: kubernetes-dashboard
" F) N0 `8 t/ M% l name: kubernetes-dashboard
8 Z+ G3 v4 N K: {% \ namespace: kube-system- V6 [8 L) d' P5 \! r
rules: t! @, r9 \* Y0 ~; F9 n3 O) i& x$ @8 s- n
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.9 \9 p* B8 K8 v
- apiGroups: [""]' {; o- _. r' a. a
resources: ["secrets"]
: A. ?7 g; y4 U; _: C) F7 I" L resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]# d |) w5 p% W% G' `7 ^7 Z: ?
verbs: ["get", "update", "delete"]
9 R+ _* r3 R' w4 n # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.% x2 |2 j- ?7 l, j8 o
- apiGroups: [""]
0 ^+ f% |8 s( z; T6 g resources: ["configmaps"]% S* O; E3 s7 @% ~
resourceNames: ["kubernetes-dashboard-settings"]
; f3 T m2 T' Q: z7 c! s t verbs: ["get", "update"]
& X& }: s7 x6 \& v # Allow Dashboard to get metrics.
! E* M! c- }" Q# {* n, r6 I) r$ ^, ` - apiGroups: [""]
1 ?$ `, X+ ] L/ [3 w resources: ["services"]. K% m. B9 p2 O; i4 h: |
resourceNames: ["heapster", "dashboard-metrics-scraper"]1 [/ p. \: `3 x. v' y: z$ B
verbs: ["proxy"]
) X" f8 t) O( N, {1 D+ M - apiGroups: [""]" u9 h0 C3 c4 j* N% q
resources: ["services/proxy"]. ]7 P6 ^6 M# Q1 q" d6 p
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
( T3 ?" `! M; s# [. R8 o0 s9 @( v verbs: ["get"]
, x8 N4 u# K1 q& h# U- p( O$ k% k/ j) l+ U2 l% u5 d; y$ K
---& R/ v0 I7 n5 J1 {/ R; Q
kind: ClusterRole
5 \1 N& {" }$ \. s9 l: A( _. k* p& _3 kapiVersion: rbac.authorization.k8s.io/v1
S/ ?: M' C# `metadata:# V1 C+ V; C$ g- x
labels:
: u7 l% T( S: r% \. D+ I k8s-app: kubernetes-dashboard
6 I0 d2 V" S$ J name: kubernetes-dashboard
' L6 c" T$ G3 g5 `/ S2 {# qrules:
8 G9 n2 P! x: X9 g/ J1 c) [ [ # Allow Metrics Scraper to get metrics from the Metrics server
0 m3 _: v' W0 h6 i- G* D - apiGroups: ["metrics.k8s.io"]
. x, b* a+ w: C( d Y. ^ resources: ["pods", "nodes"]
; }7 a& v/ Y+ X verbs: ["get", "list", "watch"]8 z+ _, P" ?* ?* i
; L8 a |; l" g2 G) I9 C x
---
3 b, m! p9 G# W: u# kapiVersion: rbac.authorization.k8s.io/v12 J7 g; G3 D& L. {- N, X5 {# _
kind: RoleBinding
+ J+ A1 A. a% t) |5 Gmetadata:
0 S( H! q) W: R: h; _" q$ S labels:# B! V% ]5 \$ e" \
k8s-app: kubernetes-dashboard
6 _+ E, Z1 w; k" W& Q name: kubernetes-dashboard
( H0 N9 w$ c4 c3 R) U3 g0 J namespace: kube-system' ~* v0 i4 |8 C+ y
roleRef:
$ |4 D" e, b/ K+ f' E) T L1 M- d apiGroup: rbac.authorization.k8s.io
' W3 O7 W' K* y4 Y+ d l8 { kind: Role
9 ]4 m4 ^8 I3 |7 `' b6 b name: kubernetes-dashboard7 ?6 v1 |+ Q+ e9 Z* W0 S
subjects:0 A* ^5 L' R# p Q
- kind: ServiceAccount8 T( S$ W" K# K7 @
name: kubernetes-dashboard m4 |% O Z$ j& q% j
namespace: kube-system
* |. a* I( x* D5 X7 o7 e: _' g# S0 d/ ^" C
---2 b! W: Q6 F" E& J* o* h4 M
apiVersion: rbac.authorization.k8s.io/v1' M7 W5 m/ B& j1 {9 T }# r! q
kind: ClusterRoleBinding
9 d$ J/ c8 x9 Pmetadata:
6 u" X2 m5 g A" i+ O name: kubernetes-dashboard+ G: p" f H; d) i- q# Q1 q; {
roleRef:
: _; F M" k5 O3 L2 X7 @# @6 b% ~ apiGroup: rbac.authorization.k8s.io
8 \5 K u! Z8 ^- W kind: ClusterRole
! _3 Y0 m- B5 d7 s6 f name: kubernetes-dashboard
, {4 r- ^* C; W+ E' f" m( s2 O& fsubjects:
' h9 \# J9 o3 ~' d% H- V& b - kind: ServiceAccount( A) O0 k' e: L/ b8 g0 A0 e
name: kubernetes-dashboard
7 L4 t2 @' D! E2 q. [, N namespace: kube-system6 W# }5 L* g; Y, v7 n
. @1 l$ m7 u* d
---
' ^% H7 h: \, qkind: Deployment7 E7 Y; ?) d* ^5 {
apiVersion: apps/v17 S( O0 k) ?: J$ z( X3 R: C& Q
metadata:
- f& ?5 j5 h8 L: S7 @2 w labels:0 u q0 | H9 o6 s5 f# V6 G
k8s-app: kubernetes-dashboard
- C. |( {7 H9 L9 H2 H( n6 ? name: kubernetes-dashboard$ q `4 w0 B- L
namespace: kube-system
8 F4 e3 s- j0 ^" ]! rspec:! f& k5 E1 g& u
replicas: 1
" H3 j# R6 A! Y; Q revisionHistoryLimit: 102 b7 J x8 X* Z* _+ \/ g
selector:+ v2 {3 J1 t! l3 ^& E
matchLabels:9 D8 s( F2 ?* ]) L Q
k8s-app: kubernetes-dashboard
+ c. x8 z/ g% j; ] template:8 _" d# x1 k* \& o+ v: B
metadata:" o: S. s) Q" b* Z/ H
labels:0 @# p+ l7 _( n9 W
k8s-app: kubernetes-dashboard
" D4 Z7 P# ^% z6 j' E! [ spec:' V+ Q) l$ e. [$ |* E \
containers:
% { H+ c! {; P8 M7 A6 c. ]! w: |! A - name: kubernetes-dashboard
$ [) ?6 M+ e, n- V0 @ image: kubernetesui/dashboard:v2.4.0. V* X7 Y6 S& H9 r: ~5 E
imagePullPolicy: IfNotPresent
: x. ]9 V- n* Y9 I3 e7 V/ {+ `6 T ports:2 X" M3 H F- f* z
- containerPort: 8443
) U( s9 m, W3 y6 G* Q% m. g5 ]9 G7 F9 H protocol: TCP
6 x4 k& ^+ ~5 Z args:3 Y1 e8 q. I/ b
- --auto-generate-certificates
. R" \+ t% x, l% m y2 W) ? - --namespace=kube-system
* B2 \" k6 v6 O( e2 k- b* i - --token-ttl=1800
9 ~. H3 U' r3 Y7 y - --sidecar-host=http://dashboard-metrics-scraper:8000
; G% V; x/ u7 k9 ?% w2 S& h # Uncomment the following line to manually specify Kubernetes API server Host. V- h, D4 q( W6 c- i. { j
# If not specified, Dashboard will attempt to auto discover the API server and connect
o) y6 X6 ^0 z7 E( f$ r% Q # to it. Uncomment only if the default does not work.
& ^4 f7 U& g, ^9 |( q2 h5 f9 v' |9 l # - --apiserver-host=http://my-address:port
, \1 B) h# N$ e1 y& m volumeMounts:$ c0 n& n+ u5 Q1 ?
- name: kubernetes-dashboard-certs
5 P5 w* P2 ~: A* t5 Z mountPath: /certs2 x9 ?$ C# j' |7 F" l2 q. M; n) y: W
# Create on-disk volume to store exec logs7 j- D4 J$ @0 G. S
- mountPath: /tmp
n c3 h) f* \+ E name: tmp-volume
) k5 ^, Z( A9 \" h, y/ ? livenessProbe:) f! c4 r1 b" t2 ]3 w* r; l1 R
httpGet:" @% ~2 m7 c) f1 ]2 S( {' j q
scheme: HTTPS7 j$ N& W! \& X& I6 t
path: /9 ~( N1 \# f! d, ^! x( a4 Y4 V, ~
port: 8443
4 X1 u& {7 V7 i8 E8 ^% |, K" G initialDelaySeconds: 307 _) \2 B1 b: I4 n3 q2 k4 N
timeoutSeconds: 30
2 R- X0 U, h) u* h0 a- Y z2 B& ^ securityContext:
# ?" b$ h1 M* F. m allowPrivilegeEscalation: false- y. q8 P+ ]1 ^
readOnlyRootFilesystem: true
0 w5 z9 | G. I8 T; v runAsUser: 1001
9 ~$ j8 l0 C7 W/ p$ t+ a runAsGroup: 2001: W: X# s" H$ T& f
volumes:% }' d/ l1 v9 y% F
- name: kubernetes-dashboard-certs( G D: P1 V8 H# F9 V+ `3 L
secret:# y: E. K3 m4 P; u
secretName: kubernetes-dashboard-certs! G6 Z3 N. x& I( y' ]% @
- name: tmp-volume3 |* ]0 x1 P5 f2 f' Q1 t
emptyDir: {}' F6 I3 i6 S/ j
serviceAccountName: kubernetes-dashboard
2 u5 q* n7 T& m; ~+ F* z nodeSelector:5 l( r$ V( m, g/ e( `2 { M+ p
"kubernetes.io/os": linux6 u# @( L+ S" ]0 `. c3 g
# Comment the following tolerations if Dashboard must not be deployed on master
1 X! M3 V+ g+ \' F; z1 @+ }' Z9 q7 u tolerations:, x$ H+ }& X7 u2 ]% h( X9 ^
- key: node-role.kubernetes.io/master" R1 B8 S& m" t: V' x5 d
effect: NoSchedule5 o4 R9 \5 b) a0 @
1 e2 Q6 |4 G0 ^
---' D- ^! g$ J+ c
kind: Service! v2 Y9 U1 m) o3 B& |
apiVersion: v1% T" d- Q" Z1 Y. x1 E
metadata:' S6 O4 T0 \* o+ Z
labels:
- A. A0 `& v; Z1 P6 h! F) V/ g k8s-app: dashboard-metrics-scraper
! U5 a% b$ ?2 O }( b$ o( j name: dashboard-metrics-scraper4 K& D, A: `& n" a; v. `7 d0 A* X
namespace: kube-system. z* e- T- b) o4 M5 Z
spec:
8 Q( l: m$ v, y! e1 y ports:
w; Q& ^+ X+ G. W. c - port: 8000/ f! |! b- y: `* |( |3 T
targetPort: 8000
+ B# |' d, F" ] selector:
+ l. a [5 i% L a9 ?, ^ k8s-app: dashboard-metrics-scraper
: C0 Y6 { h; O7 G2 e5 f# T+ y
! ^$ ?: i4 q8 l" a. g---
, u$ N: l$ W- s. {kind: Deployment
$ k# A4 C$ R6 b$ a) X3 J: S$ z$ n6 M2 aapiVersion: apps/v15 {' J' ~3 c3 g* o0 @
metadata:
' N! D5 l- n# P0 r0 D( _ labels:
" p3 H. ^; E+ o& s2 t k8s-app: dashboard-metrics-scraper
& c/ }4 H: n8 x p name: dashboard-metrics-scraper+ Y2 m! M6 ~0 a/ `( h$ K
namespace: kube-system d! @; e6 ^( \. N
spec:
: y N& A# G( d- q& Z3 C replicas: 1
0 ^; E7 C. a( ?' o; x0 ?+ K revisionHistoryLimit: 103 P6 W( P- Q7 M" e0 }/ `+ I8 n2 P4 M
selector:
; W* H k4 H# O+ H, D$ d; K matchLabels:
: k3 g7 T( @' u# x% f7 G; }7 ? k8s-app: dashboard-metrics-scraper3 A, Z2 l( Y8 t9 a! z
template:" ^) X9 e Q2 \
metadata:
* O4 b# X& ^& p) B: | labels:
2 {% s9 ^& v! B Z @) E6 n k8s-app: dashboard-metrics-scraper- R7 \. U) x) E6 c
spec:
9 b4 [" f+ i9 m4 G securityContext:
4 O( s7 b- u( e! W, c1 T: i seccompProfile: T9 O) u3 u: O/ r: u P1 [6 b- ]2 S
type: RuntimeDefault# t* l3 G4 ~0 J3 N
containers:
' K9 s8 f# S1 z - name: dashboard-metrics-scraper
7 S8 E) h1 B4 k* e6 L image: kubernetesui/metrics-scraper:v1.0.7
9 J( \3 T2 I/ a" L" F/ w+ s imagePullPolicy: IfNotPresent
* S% R1 k& h( j6 u. b ports:* M( s8 [1 L& d4 Q! k* Y5 l4 x
- containerPort: 8000
W2 N: T: s2 t) f, d protocol: TCP
9 K: p; T5 L f2 N livenessProbe:
( R/ x- H x Z; i httpGet:5 G3 X/ }" x- L" c( o
scheme: HTTP
$ ]% p) R- Q3 Y" _ path: /
: N5 ~1 y7 L9 U7 Z; Q* P4 I port: 8000
) {1 |1 ~7 @. f initialDelaySeconds: 30
) A5 I [: _8 A9 Z Z! i timeoutSeconds: 30* R9 y7 O3 i/ }3 k& V3 a9 D
volumeMounts:
& R ~1 w& z9 S6 j - mountPath: /tmp
N5 R9 M+ L1 _- U name: tmp-volume
- X, B) }6 A1 P* r( K: f' E7 a' a securityContext:
& O5 o( x8 q: S! W5 ? allowPrivilegeEscalation: false, W6 p7 U( Y& S4 Q9 @
readOnlyRootFilesystem: true+ {$ D+ M3 ]# P& H6 W
runAsUser: 1001
% d/ O, s1 F& `1 k( H5 Q! j runAsGroup: 2001/ V: f5 R5 g& d- B
serviceAccountName: kubernetes-dashboard
: O& A3 Z$ i ?& E; k; x! V ] nodeSelector:
; u- l9 @! I) w7 H& j "kubernetes.io/os": linux. @* ~6 y1 s7 H( w- F
# Comment the following tolerations if Dashboard must not be deployed on master! S5 ~3 z5 n& ^( \/ L
tolerations:
H: Q& |; H: S; A7 i - key: node-role.kubernetes.io/master
5 c4 L( g7 o# t" K3 [+ v \ effect: NoSchedule
, R/ X) X1 ^8 ?# c volumes:7 D! N) E, R- V7 x8 H
- name: tmp-volume) [" W- R& U/ ^3 P5 M H/ l& V3 a, V! ~
emptyDir: {}
7 ^+ s2 X3 @" j6 F0 l! N( t, m, S导入 dashboard 镜像7 ^8 O! P" B# [
for i in 192.168.91.19 192.168.91.20;do \
* l% C7 V. d5 D. r D/ n3 A2 dscp /approot1/k8s/images/dashboard-*.tar $i:/tmp/
/ M3 _' T& y, r1 N5 b& gssh $i "ctr -n=k8s.io image import /tmp/dashboard-v2.4.0.tar && rm -f /tmp/dashboard-v2.4.0.tar"; \8 \) i( F N+ W3 Z- g& l4 u6 f
ssh $i "ctr -n=k8s.io image import /tmp/dashboard-metrics-scraper-v1.0.7.tar && rm -f /tmp/dashboard-metrics-scraper-v1.0.7.tar"; \
9 K8 q }# p2 L* `$ J7 Ldone
% m! `3 K( ]" {$ s查看镜像) p6 R8 i4 C, D7 U7 C
: G& X& x: W# Q0 {for i in 192.168.91.19 192.168.91.20;do \" b: w# L0 f; r9 {6 `+ a, z8 u
ssh $i "ctr -n=k8s.io image list | egrep 'dashboard|metrics-scraper'"; \: _' C% ^$ u1 i3 O
done& [6 \* B8 S0 t2 e7 f
在 k8s 中运行 dashboard 组件5 k; S3 f% H6 B8 P; V0 n( o8 [7 T
kubectl apply -f /approot1/k8s/tmp/service/dashboard.yaml9 j+ ^" p" a) s% m
检查 dashboard pod 是否运行成功
3 }4 h: {+ c, ~ N$ ^' [% _5 Z { kkubectl get pod -n kube-system | grep dashboard8 b1 b% |9 R8 _$ a6 X5 T; {
预期输出类似如下结果
~2 E. C! L4 `9 ^8 \! [8 L. B P# `" O! G# c: `
dashboard-metrics-scraper-799d786dbf-v28pm 1/1 Running 0 2m55s
4 H) o. R3 }8 A9 W- s1 C0 Lkubernetes-dashboard-9f8c8b989-rhb7z 1/1 Running 0 2m55s' S- a# |9 J& J; t7 R* v9 o- w: |, ]
查看 dashboard 访问端口
; t5 M7 T- ~' m7 f在 service 当中没有指定 dashboard 的访问端口,所以需要自己获取,也可以修改 yaml 文件指定访问端口8 B$ B) G, u; l0 q
$ U1 t4 b# a* O" o预期输出类似如下结果
) P! y4 L9 }+ N" |1 n# u' X
7 k& a$ N3 {0 u0 V, J+ h我这边是将 30210 端口映射给 pod 的 443 端口8 d( T4 V+ R0 D) d; _8 j8 F* B
" v. S2 L1 C7 {! |
kubernetes-dashboard NodePort 10.88.127.68 <none> 443:30210/TCP 5m30s
! z/ b3 M7 M) `; c7 a- W# y根据得到的端口访问 dashboard 页面,例如: https://192.168.91.19:302105 w3 X: a' T! b8 J5 P
8 z4 C" C0 `" Q9 G查看 dashboard 登录 token
* V0 F3 B3 b1 F" J5 g获取 token 文件名称
9 D7 P. V l$ p1 P& M! v* ^! m' G: W! t! o. _ @* w
kubectl get secrets -n kube-system | grep admin
6 n5 A% w( a1 G& `3 \! Q. u( Q: F预期输出类似如下结果
" d5 m* a# B* N1 h& Z/ y
I& P/ t- [$ V \1 k' |" padmin-user-token-zvrst kubernetes.io/service-account-token 3 9m2s- _9 A- B) n1 d. Z) |
获取 token 内容 ~9 k$ S, R5 w: U& A2 U' l
2 t# y; p1 K. s( k: A, R% x
kubectl get secrets -n kube-system admin-user-token-zvrst -o jsonpath={.data.token}|base64 -d) T& p( d% u+ u9 o' f
预期输出类似如下结果& {: V+ J: K) y8 Z/ l
( y4 _7 o0 B, o# [8 ?eyJhbGciOiJSUzI1NiIsImtpZCI6InA4M1lhZVgwNkJtekhUd3Vqdm9vTE1ma1JYQ1ZuZ3c3ZE1WZmJhUXR4bUUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLXp2cnN0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhYTE3NTg1ZC1hM2JiLTQ0YWYtOWNhZS0yNjQ5YzA0YThmZWYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.K2o9p5St9tvIbXk7mCQCwsZQV11zICwN-JXhRv1hAnc9KFcAcDOiO4NxIeicvC2H9tHQBIJsREowVwY3yGWHj_MQa57EdBNWMrN1hJ5u-XzpzJ6JbQxns8ZBrCpIR8Fxt468rpTyMyqsO2UBo-oXQ0_ZXKss6X6jjxtGLCQFkz1ZfFTQW3n49L4ENzW40sSj4dnaX-PsmosVOpsKRHa8TPndusAT-58aujcqt31Z77C4M13X_vAdjyDLK9r5ZXwV2ryOdONwJye_VtXXrExBt9FWYtLGCQjKn41pwXqEfidT8cY6xbA7XgUVTr9miAmZ-jf1UeEw-nm8FOw9Bb5v6A
$ i; k: j0 z& n L
! f' H% T2 r* K到此,基于 containerd 二进制部署 k8s v1.23.3 就结束了$ Q9 s7 Y- _2 c j: ~8 g |
" a/ M! n: g: Q$ S |
|