思有所皈,绪有所依

给万千思绪,寻一寄存之所

k3s文档

中文文档:https://docs.rancher.cn/docs/k3s/_index

准备离线文件

https://github.com/k3s-io/k3s/releases下载以下文件:
* k3s-airgap-images-amd64.tar.zst
* k3s

https://rancher-mirror.rancher.cn/k3s/k3s-install.sh下载k3s-install.sh文件。

离线安装(Ubuntu 22.04)

  1. 将k3s-airgap-images-amd64.tar.zst文件上传到服务器的/var/lib/rancher/k3s/agent/images/目录下

    1
    2
    sudo mkdir -p /var/lib/rancher/k3s/agent/images/
    sudo cp k3s-airgap-images-amd64.tar.zst /var/lib/rancher/k3s/agent/images/
  2. 将k3s文件上传到服务器的/usr/local/bin/目录下

    1
    2
    sudo cp k3s /usr/local/bin/
    sudo chmod +x /usr/local/bin/k3s
  3. 将k3s-install.sh文件上传到服务器

  4. 执行安装脚本

    server1
    1
    2
    3
    4
    5
    chmod +x k3s-install.sh
    sudo INSTALL_K3S_SKIP_DOWNLOAD=true \
    INSTALL_K3S_EXEC='server --token=23f0fba79fc84fd5962279908c86d05e --cluster-init' \
    ./k3s-install.sh

    servern
    1
    2
    3
    4
    chmod +x k3s-install.sh
    sudo INSTALL_K3S_SKIP_DOWNLOAD=true \
    INSTALL_K3S_EXEC='server --token=23f0fba79fc84fd5962279908c86d05e --server https://server1:6443' \
    ./k3s-install.sh

让k3s使用私有镜像仓库

放一个registries.yaml文件进行配置

/etc/rancher/k3s/registries.yaml
1
2
3
4
mirrors:
docker.io:
endpoint:
- "http://registry.example.com:5000"

重启k3s

1
sudo systemctl restart k3s

挂载NAS

在阿里云控制台查看具体操作

helm安装(ubuntu 22.04)

1
2
3
4
5
6
7
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config

sudo snap install helm --classic

helm repo add bitnami https://charts.bitnami.com/bitnami

helm repo list

helm3不再需要Tiller和helm init

使用Lens访问

https://k8slens.dev/下载Lens安装包,支持windows,需要通过XShell的隧道来打通网络。
在Lens的Clusters界面增加(右下角的大加号),选择菜单Add from kubeconfig,复制粘贴K3s的kubeconfig(/etc/rancher/k3s/k3s.yaml)即可。

使用Docker下载镜像再导入到k8s

Docker下载

1
docker save registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.9.2 -o kube-state-metrics-v2.9.2.tar

Docker导入

1
docker image load -i kube-state-metrics-v2.9.2.tar

k3s导入

1
2
k3s ctr image import kube-state-metrics-v2.9.2.tar
k3s ctr image ls|grep kube-state-metrics

注意:如果镜像的下载策略(imagePullPolicy)是Always,则始终会重新下载镜像,所以要使用导入的镜像,需要将镜像下载策略改为IfNotPresent

kube-prometheus

参考:https://github.com/prometheus-operator/kube-prometheus

1
2
3
4
5
6
7
8
9
kubectl apply --server-side -f manifests/setup
kubectl wait \
--for condition=Established \
--all CustomResourceDefinition \
--namespace=monitoring
kubectl apply -f manifests/

kubectl port-forward pod/grafana-748964b847-vtnk8 3000 3000 -n monitoring
默认账号密码: admin/admin

安装Docker(Ubuntu)

1
sudo apt install docker.io

配置镜像加速(阿里云)

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://??????.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

rancher(弃用)

Rancher安装后默认开启了一个内置的k3s集群,但是无法增加自建的k8s集群?或许只用k3s才是最简单的方式?毕竟Rancher带来了更多的复杂性和不可控性。

持久化存储(longhorn)

安装

1
2
3
wget https://raw.githubusercontent.com/longhorn/longhorn/v1.5.1/deploy/longhorn.yaml
kubectl apply -f longhorn.yaml
kubectl get sc

Dashboard

官方文档: accessing-the-ui

1
kubectl port-forward svc/longhorn-frontend 30080:80 -n longhorn-system

部署私有镜像仓库

启动私有镜像仓库

1
2
3
4
5
6
docker run -d\
-p 5000:5000\
--restart unless-stopped\
--name registry\
-v /mnt/registry-data:/var/lib/registry\
registry:latest

UI界面访问(joxit/docker-registry-ui)

大致找了一下,joxit/docker-registry-ui可以用(至少还在更新),github

docker-compose.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
version: '3.8'

services:
registry-ui:
image: joxit/docker-registry-ui:2.5.7
restart: unless-stopped
ports:
- 18080:80
environment:
- SINGLE_REGISTRY=true
- REGISTRY_TITLE=Docker Registry UI
- DELETE_IMAGES=true
- SHOW_CONTENT_DIGEST=true
- REGISTRY_URL=http://localhost:5000
- SHOW_CATALOG_NB_TAGS=true
- CATALOG_MIN_BRANCHES=1
- CATALOG_MAX_BRANCHES=1
- TAGLIST_PAGE_SIZE=100
- REGISTRY_SECURED=false
- CATALOG_ELEMENTS_LIMIT=1000
container_name: registry-ui
networks:
- registry-net

registry-server:
image: registry:2.8.2
restart: unless-stopped
ports:
- 5000:5000
environment:
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://localhost:18080]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'
REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'
REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
volumes:
- /your-path/registry-data:/var/lib/registry
container_name: registry-server
networks:
- registry-net
networks:
registry-net:
1
2
3
4
# 启动
docker-compose up -d
# 关闭
docker-compose down

避坑指南:如果是使用XShell这样的终端,可以通过XShell的隧道来从工作终端访问内网,但是需要把registry-server的5000端口,以及registry-ui的18080端口都映射到本地。

标记镜像并推送到私有仓库

1
2
docker tag registry:latest 127.0.0.1:5000/registry:v2.7.1
docker push 127.0.0.1:5000/registry:v2.7.1

用curl查看仓库中的镜像

1
2
3
4
5
# 查看仓库中镜像
curl -X GET 127.0.0.1:5000/v2/_catalog

# 查看某个具体镜像的tag
curl -X GET 127.0.0.1:5000/v2/image_name/tags/list

如果出现异常可以加-v或–verbose参数以详细模式运行curl,方便排查

从私有仓库拉取镜像

其他主机使用私有仓库镜像,则需要修改daemon.json文件,并使之生效:

1
2
3
4
5
6
7
8
9
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://your_id.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.1.1:5000"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

解决Docker镜像无法pull的问题

国外平台的Docker镜像无法下载时,可以通过DaoCloud的公开镜像加速来下载,即增加m.daocloud.io前缀。

参考: DaoCloud公开镜像加速

用helm安装zookeeper

搜索需要的版本:

1
helm search repo bitnami/zookeeper -l|grep 3.8

下载指定的版本(这个版本是helm的chart版本,不是zookeeper的版本):

1
helm fetch bitnami/zookeeper --version 11.4.11

解压下载的tgz文件,修改values.yaml进行定制化配置:

1
2
3
tar -zxvf zookeeper-11.4.11.tgz
cd zookeeper-11.4.11
vi values.yaml

修改values.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
replicaCount: 3
...
persistence:
storageClass: longhorn
size: 2Gi
...
resources:
limits: {}
requests:
memory: 128Mi
cpu: 50m

安装及输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
helm install zookeeper .

NAME: zookeeper
LAST DEPLOYED: Tue Jul 30 13:17:31 2024
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: zookeeper
CHART VERSION: 11.4.11
APP VERSION: 3.8.2

** Please be patient while the chart is being deployed **

ZooKeeper can be accessed via port 2181 on the following DNS name from within your cluster:

zookeeper.default.svc.cluster.local

To connect to your ZooKeeper server run the following commands:

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=zookeeper,app.kubernetes.io/instance=zookeeper,app.kubernetes.io/component=zookeeper" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -- zkCli.sh

To connect to your ZooKeeper server from outside the cluster execute the following commands:

kubectl port-forward --namespace default svc/zookeeper 2181:2181 &
zkCli.sh 127.0.0.1:2181

查看zookeeper集群状态:

1
kubectl exec -it zookeeper-0 -- zkServer.sh status

安装dubbo-admin

参考:https://github.com/apache/dubbo-admin

Admin 控制台的最新稳定版本是0.5.0,貌似很久没更新了。
在kubernetes中安装,需要先调整一下dubbo-admin\kubernetes\dubbo-admin.yaml里的配置:

1
2
3
4
5
6
7
8
...
data:
application.properties: |-
admin.root.user.name: root
admin.root.user.password: root
...
admin.check.signSecret: adkfkdkd13413
...

注意:admin.check.signSecret默认是空,如果不填写,则无法登录。

部署:

1
kubectl apply -f dubbo-admin.yaml

端口转发:

1
kubectl port-forward -n default deployment/dubbo-admin 38080:8080

用浏览器访问:http://localhost:38080

将文件或者文件夹转换为ConfigMap

https://blog.csdn.net/m0_51964671/article/details/135480707
https://blog.csdn.net/lewyu521/article/details/139546315

1
2
3
$ kubectl create configmap testfile --from-file pods/

$ kubectl get configmaps testfile -oyaml

注意:从文件创建configmap时,建议把Windows(CR LF)格式的配置文件转换为Unix(LF)格式,这样输出为yaml文件时,才不会出现CR LF的转义符。

利用echo进行base64编码和解码

1
2
3
echo -n "admin:admin" | base64

echo -n "YWRtaW46YWRtaW4=" | base64 -d

Argo CD

安装:

1
2
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

访问:

1
2
3
4
5
6
#查看admin账号的默认密码
kubectl get secret argocd-initial-admin-secret -n argocd -oyaml
echo -n "..." | base64 -d

#端口转发后用浏览器访问:https://localhost:8443
kubectl port-forward svc/argocd-server -n argocd 8443:443

argocd的UI上配置仓库连接时,采用https和账号、密码的方式比较简单

安装CLI(需先从github下载argocd-linux-amd64):

1
2
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64

使用CLI:

1
2
3
4
argocd login https://localhost:8443 --username admin --password ...

# 查看集群状态
argocd cluster list

HPA(Horizontal Pod Autoscaler)

先调整deployment的配置,主要是将replicas设置为1,并增加资源的请求和限制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: apps/v1
kind: Deployment
metadata:
name: your-deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: your-deployment-name
template:
metadata:
labels:
app: your-deployment-name
spec:
terminationGracePeriodSeconds: 60
containers:
- name: your-deployment-name
image: youre-image-name:v1.0.0
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "2Gi"
cpu: "0.5"
limits:
memory: "3Gi"
cpu: "0.8"

之所以增加资源的requests和limits,是因为HPA的资源占用百分比计算,是以资源请求的值来计算的。如果不设置资源请求,则HPA就无法计算资源的占比,从而无法进行扩缩容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: your-deployment-name
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: your-deployment-name
minReplicas: 1
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # 50%
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 100 # 100%
behavior:
# 缩容
scaleDown:
stabilizationWindowSeconds: 300 # 稳定窗口期,默认300s
policies:
- type: Pods
value: 1
periodSeconds: 15 # 检查周期,默认15s
# 扩容
scaleUp:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 15

查看HPA的状态:

1
2
kubectl get hpa
kubectl describe hpa

望岳

唐·杜甫
岱宗夫如何?齐鲁青未了。
造化钟神秀,阴阳割昏晓。
荡胸生曾云,决眦入归鸟。
会当凌绝顶,一览众山小。

阅读全文 »

run命令中指定entrypoint

有时需要查看镜像的文件,或者在实例上去进行一些测试,就可以通过--entrypoint来启动shell,例如:

1
docker run --entrypoint /bin/sh -it --rm some-app

Fix No chain/target/match by that name

最近在Alibaba Cloud Linux 3上使用audo apt update进行系统升级后,某个Docker容器无法重启,错误如下:

1
2
Error response from daemon: Cannot restart container some-app: driver failed programming external connectivity on endpoint some-app (88301987d72d07ba99c1630461e1ade9d1fb53879b1d6f94fc8571ac7db7e2a6):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9015 -j DNAT --to-destination 172.17.0.3:9015 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1))

首先排除了iptables的原因,因为我们在做容器化部署的服务器上,都禁用了iptables。

然后怀疑是系统更新的时候,影响到了Docker容器的某些配置,导致容器无法重启。但是重建容器后,还是无法重启,报一样的错误。

最后搜索了一下,找到了解决办法:
参考:docker启动容器报错(iptables failed)

重启docker服务即可:

1
systemctl restart docker

容器的健康检测

如果在Dockerfile或者docker run命令里进行了健康检测,容器启动后查看状态会多出一个信息:healthy或者unhealthy。

1
2
3
# docker ps
... STATUS
... Up 19 minutes (healthy)

在Dockerfile里配置健康检测

Dockerfile
1
HEALTHCHECK --interval=10s --timeout=2s --start-period=30s --retries=3 CMD curl --silent --fail http://localhost:7015/actuator/health || exit 1

在容器启动时指定健康检测参数

1
2
3
4
5
6
7
8
docker run ...
--health-interval=10s \
--health-timeout=2s \
--health-start-period=30s \
--health-retries=3 \
--health-cmd="curl --silent --fail http://localhost:7017/actuator/health || exit 1" \
--restart on-failure \
...

自动重启unhealthy的容器

参考Github项目: Autoheal
大致是说本来docker run有一个issue,或者说应该有那么一个功能,参数--exit-on-unhealthy,默认值true,在容器unhealthy时就退出。再配合--restart=on-failure,来实现容器的自动重启。在exit-on-unhealthy没实现之前,就用这个Autoheal来实现这个功能。

1
2
3
4
5
6
docker run -d \
--name autoheal \
--restart=unless-stopped \
-e AUTOHEAL_CONTAINER_LABEL=all \
-v /var/run/docker.sock:/var/run/docker.sock \
willfarrell/autoheal
  • AUTOHEAL_CONTAINER_LABEL的默认值是autoheal,表示Autoheal会监视带有标签--label autoheal=true的容器。
  • 设置AUTOHEAL_CONTAINER_LABEL=all则是监视所有正在运行的容器。
  • 也可以自定义AUTOHEAL_CONTAINER_LABEL的值,比如AUTOHEAL_CONTAINER_LABEL=myapp,这会监视所有带myapp=true标签的容器。(说实话,官方的这句Set ENV AUTOHEAL_CONTAINER_LABEL to existing label name that has the value true.,最初让我懵了一下。)

莫名其妙的“操作超时”

在用C#的HttpWebRequest写一个HTTP客户端请求时,遇到了一个莫名其妙的问题,就是在发送POST请求时,总是报“操作超时”的错误。核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
HttpWebRequest wbRequest = (HttpWebRequest)WebRequest.Create(url);
wbRequest.Method = "POST";
wbRequest.ContentType = "application/json";

byte[] data = Encoding.UTF8.GetBytes(content);
wbRequest.ContentLength = data.Length;
using (Stream requestStream = wbRequest.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
requestStream.Flush();
}
...
HttpWebResponse wbResponse = (HttpWebResponse)wbRequest.GetResponse();

在执行bRequest.GetResponse()时会卡住,一直等待直到报“操作超时”的错误。

分析与排查

代码问题的几率很小

这段代码没啥好说的,是老系统里千锤百炼留下来的基础代码。从网络上找到的教程什么的,大致也是这样写的,所以代码的问题的几率很小。

也不是服务端处理慢

服务端的响应不涉及复杂的业务处理,这个可以直接排除。

用Postman测试可以正常访问

用Postman测试,没有出现“操作超时”的错误。这个问题就很奇怪了,Postman的请求和代码里的请求应该是一样的,为什么Postman可以正常访问,而代码里就不行呢?

用Fiddler抓包分析

只有用Fiddler抓包分析,来看看代码的request跟Postman的请求有什么差异。发现代码里的请求,主要差异是多了一个Expect: 100-continue的Header。

Postman复现问题

Postman加上100-continue的Header,就可以复现“操作超时”的问题。

罪魁祸首之100-continue

查了一下资料,100-continue是HTTP 1.1里设计的一个状态码,在发送请求体之前,先发送一个Expect: 100-continue,如果服务器响应了100-continue,那么就会继续发送请求体。

这个设计的目的是为了在发送大量数据时,先确认服务器是否接受这个请求,如果不接受,就不用发送大量的数据了,从而减少网络带宽的浪费。

这就跟本文的问题对上了,刚好是带请求体的POST请求,所以先发送Expect: 100-continue,但是服务器没有响应100-continue,就一直等待到“操作超时”。

解决方案

定位到具体的原因后,解决起来就容易了,有两种方案(任选其一):

客户端:禁用100-continue

1
wbRequest.ServicePoint.Expect100Continue = false;

服务端:支持100-continue或者忽略100-continue

这个得看服务端的网关是什么了,可以配置为HTTP协议为1.1,或者把请求头里的Expect: 100-continue过滤掉。

未能创建 SSL/TLS 安全通道

最近将服务器升级到Ubuntu 22.04.2 LTS后,部分终端的.Net framework应用连接时报错:“请求被中止:未能创建SSL/TLS 安全通道”。

这个问题以前也出现过,终端的操作系统是Windows 7,只能安装.Net Framefork 4.0,但是4.0不支持TLS1.2,而Ubuntu升级后不支持TLS1.0和1.1,这就导致无法建立SSL/TLS安全通道。

当时主要参考 ubuntu不支持tls1.0解决,修改openssl的配置/etc/ssl/openssl.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
//在第一行增加:
openssl_conf = default_conf

//在尾部增加:
[default_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1
CipherString = DEFAULT:@SECLEVEL=1

Ubuntu升级过程中,都是选择的维持现有配置,所以/etc/ssl/openssl.cnf里还是有这些配置,不知道为什么没有生效。

修改Nginx的配置

参考 Enable TLS 1.0 and TLS 1.1 on Ubuntu 20.04

修改nginx的配置:

nginx.conf
1
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:@SECLEVEL=1";

使用openssl测试

nginx.conf
1
2
openssl s_client -connect xiaoboey.top:443 -tls1_1
openssl s_client -connect xiaoboey.top:443 -tls1

还是没解决。。。

Event Source,即Server-sent events,主要优点是基于HTTP协议进行长连接,除了在网页里用JavaScript可以接收消息,其他的应用只要支持HTTP协议都没问题;而RabbitMQ完整实现了AMQP协议,即Advanced Message Queuing Protocol,非常成熟稳定。本文所谓的“代替”,适合的场景非常有限,如果要追求消息推送的稳定可靠,还是建议直接使用RabbitMQ。

阅读全文 »

弃坑

初步学习下来,跟k8s要解决的问题差不多,而k8s毕竟是容器编排的事实标准,所以还不如学习k8s?

Docker Swarm介绍及使用入门

Docker Swarm 搭建集群环境(高可用)
升级工作节点为管理节点:

1
docker node promote node01

Docker Swarm(四)Volume 数据(挂载)持久化

Docker Swarm(六)Label 节点标签与服务约束

docker swarm如何在指定节点运行service

TODO: 安装基于etcd的高可用k3s集群,部署Spring Boot应用。此文还未整理,暂时只是流水账。

最佳实践

保存离线安装文件

https://get.k3s.io获取安装脚本并保存为install.sh,在github上下载离线文件(主要是k3s执行程序和镜像文件)。特别是install.sh,K3s每一次的版本升级都可能会修改这个文件。笔者暂时没有找到在线获取历史版本的方法,所以如果真要自己部署K3s,把这些文件都保存下来更“靠谱”。

aliyun linux 安装Docker

参考: https://help.aliyun.com/document_detail/264695.html?spm=a2c6h.12873639.article-detail.4.54a5146d4WimM7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 添加docker-ce的dnf源
dnf config-manager --add-repo=https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装Alibaba Cloud Linux 3专用的dnf源兼容插件
dnf -y install dnf-plugin-releasever-adapter --repo alinux3-plus

# 安装docker-ce
dnf -y install docker-ce --nobest

# 验证
dnf list docker-ce

# 管理Docker守护进程
systemctl start docker #运行Docker守护进程
systemctl stop docker #停止Docker守护进程
systemctl restart docker #重启Docker守护进程
systemctl enable docker #设置Docker开机自启动
systemctl status docker #查看Docker的运行状态

安装K3s

单机

参考官网文档

国内加速安装
1
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

嵌入式etcd高可用

参考: https://docs.rancher.cn/docs/k3s/installation/ha-embedded/_index

–-docker: k3s server组件是以containerd作为容器运行时。k3s server节点默认也会启动一个agent节点,这个agent节点可以用–docker参数指定其用docker作为容器运行时。
–-disable-agent: 指定server节点不启动agent。

1
2
3
4
5
6
7
8
9
10
11
12
13
# k3s-server-1(--docker 表示agent使用docker)
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_TOKEN=SECRET sh -s - server --docker --cluster-init

systemctl enable k3s

# k3s-server-n
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_TOKEN=SECRET sh -s - server --docker --server https://172.24.46.247:6443

systemctl enable k3s

# 移除节点
kubectl delete node 节点名称

Traefik v2

K3s 1.21 及更高版本默认安装 Traefik v2

启动Traefik Dashboard

出于安全考虑,默认没有公开 Dashboard

1
kubectl -n kube-system port-forward $(kubectl -n kube-system get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000

访问地址: http://localhost:9000/dashboard/

LetsEncrypt

参考:k3s使用Let‘s Encrypt配置https入口部署

1
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.1/cert-manager.yaml
letsencrypt.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
namespace: cert-manager
name: letsencrypt
spec:
acme:
email: [email protected]
privateKeySecretRef:
name: prod-issuer-account-key
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress:
class: traefik
selector: {}

kubectl describe clusterissuer letsencrypt

ingress.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
name: myapp-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- secretName: myapp-web-tls
hosts:
- myapp.mydomain.com
ingressClassName: traefik
rules:
- host: myapp.mydomain.com
http:
paths:
- path: /web
pathType: Prefix
backend:
service:
name: myapp-svc
port:
number: 8080

K3s离线安装

尝试用离线方式来安装

部署私有镜像仓库

1
2
3
4
5
6
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v $PWD/data:/var/lib/registry \
registry:2

修改hosts:

1
vi /etc/hosts

配置私有仓库为insecure(即http)

/etc/docker/daemon.json
1
2
3
4
5
6
7
8
9
{
"insecure-registries":[
"myregistry.com:5000"
],
"registry-mirrors": [
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}

docker tag demo:v1.2 myregistry.com:5000/deom:v1.2
docker push myregistry.com:5000/deom:v1.2

批量推送镜像到私有仓库
docker images | awk ‘{print $1”:”$2}’ | xargs -I {} docker push :/{}

查看私有仓库上的镜像:
http://localhost:5000/v2/_catalog

查看demo镜像的tags
http://localhost:5000/v2/demo/tags/list

docker –debug pull myregistry.com:5000/demo:v1.2

离线安装K3s

  • https://get.k3s.io下载install.sh
  • https://github.com/rancher/k3s/releases下载k3s执行文件,放到/usr/local/bin目录下
1
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh

确认k3s是否安装成功

1
systemctl status k3s

配置k3s使用私有镜像仓库

启动时,K3s 会检查/etc/rancher/k3s/中是否存在registries.yaml文件,并指示 containerd 使用文件中定义的镜像仓库。如果你想使用一个私有的镜像仓库,那么你需要在每个使用镜像仓库的节点上以 root 身份创建这个文件。

registries.yaml
1
2
3
4
5
6
mirrors:
docker.io:
endpoint:
- "http://myregistry.com:5000"
rewrite:
"^rancher/(.*)": "mirrorproject/rancher-images/$1"

修改Host,添加myregistry.com的映射:

1
vi /etc/hosts

笔者测试的操作系统是Alibaba Cloud Linux 3.2 104 LTS,修改host就生效了,不需要重启网络。

让Docker支持http, 修改/etc/docker/daemon.json,如果没有则添加一个:

daemon.sh
1
2
3
{
"insecure-registries" : ["myregistry.com:5000"]
}

重启Docker生效:

1
systemctl restart docker

添加镜像到私有镜像仓库#

首先,从https://github.com/rancher/k3s/releases下载获取你正在使用的版本的 k3s-images.txt 文件,然后从 docker.io 中拉取 k3s-images.txt 文件中列出的 K3s 镜像,再将这些镜像重新标记成私有镜像仓库,并推送到私有镜像仓库。

示例:

1
2
3
docker pull docker.io/rancher/coredns-coredns:1.6.3
docker tag coredns-coredns:1.6.3 mycustomreg:5000/coredns-coredns
docker push mycustomreg.com:5000/coredns-coredns

查看私有镜像仓库:

1
curl http://myregistry.com:5000/v2/_catalog

Helm

安装

1
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

添加chart仓库

1
2
3
helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo add azure http://mirror.azure.cn/kubernetes/charts
helm repo add bitnami https://charts.bitnami.com/bitnami

常用命令

  • helm repo list 查看chart仓库
  • helm search repo zookeeper 搜索chart

安装zookeeper

1
2
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
helm install zookeeper bitnami/zookeeper --set replicaCount=3 --set auth.enabled=false --set allowAnonymousLogin=true

安装输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
NAME: zookeeper
LAST DEPLOYED: Wed May 31 16:03:48 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: zookeeper
CHART VERSION: 11.4.2
APP VERSION: 3.8.1

** Please be patient while the chart is being deployed **

ZooKeeper can be accessed via port 2181 on the following DNS name from within your cluster:

zookeeper.default.svc.cluster.local

To connect to your ZooKeeper server run the following commands:

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=zookeeper,app.kubernetes.io/instance=zookeeper,app.kubernetes.io/component=zookeeper" -o jsonpath="{.items[0].metadata.name}")
kubectl exec -it $POD_NAME -- zkCli.sh

To connect to your ZooKeeper server from outside the cluster execute the following commands:

kubectl port-forward --namespace default svc/zookeeper 2181:2181 &
zkCli.sh 127.0.0.1:2181
0%