我有一个独立的Kubernetes集群:
plane node - hostname kubernetes1 - 192.168.1.126
work node - hostname kubernetes2 - 192.168.1.138
我部署了这个私人存储库:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 5Gi # specify your own size
volumeMode: Filesystem
persistentVolumeReclaimPolicy: Retain
local:
path: /opt/registry # can be any path
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- kubernetes2
accessModes:
- ReadWriteMany # only 1 node will read/write on the path.
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pv1-claim
spec: # should match specs added in the PersistenVolume
accessModes:
- ReadWriteMany
volumeMode: Filesystem
resources:
requests:
storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: private-repository-k8s
labels:
app: private-repository-k8s
spec:
replicas: 1
selector:
matchLabels:
app: private-repository-k8s
template:
metadata:
labels:
app: private-repository-k8s
spec:
volumes:
- name: certs-vol
hostPath:
path: /opt/certs
type: Directory
- name: task-pv-storage
persistentVolumeClaim:
claimName: pv1-claim # specify the PVC that you've created. PVC and Deployment must be in same namespace.
containers:
- image: registry:2
name: private-repository-k8s
imagePullPolicy: IfNotPresent
env:
- name: REGISTRY_HTTP_TLS_CERTIFICATE
value: "/opt/certs/registry.crt"
- name: REGISTRY_HTTP_TLS_KEY
value: "/opt/certs/registry.key"
ports:
- containerPort: 5000
volumeMounts:
- name: certs-vol
mountPath: /opt/certs
- name: task-pv-storage
mountPath: /opt/registry
服务部署在工作节点上:
kubernetes@kubernetes1:/opt/registry$ kubectl get pods
NAME READY STATUS RESTARTS AGE
private-repository-k8s-6d5d954b4f-ldwd6 1/1 Running 0 153m
kubernetes@kubernetes1:/opt/registry$
我试图创建一个入口访问,因为我想从外部访问这个吊舱:
kubectl create namespace test
服务控制器:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: private-repository-service-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: kubernetes2
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: private-repository-service
port:
number: 5000
服务负载均衡器:
apiVersion: v1
kind: Service
metadata:
namespace: test
name: private-repository-service
spec:
#type: NodePort
selector:
app: private-repository-k8s
ports:
# By default and for convenience, the `targetPort` is set to the same value as the `port` field.
- port: 5000
targetPort: 5000
# Optional field
# By default and for convenience, the Kubernetes control plane will allocate a port from a range (default: 30000-32767)
#nodePort: 30007
当我运行curl 192.168.1.138:5000
时,没有响应。你知道我哪里错了吗?
编辑:
kubernetes@kubernetes1:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d20h
private-registry-service ClusterIP 10.103.148.234 <none> 5000/TCP 6h34m
kubernetes@kubernetes1:~$
看起来您没有任何类型的入口控制器,只想直接访问注册表。在这种情况下,您需要创建一个类型为NodePort
的服务。
apiVersion: v1
kind: Service
metadata:
namespace: test
name: private-repository-service
spec:
type: NodePort # Added
selector:
app: private-repository-k8s
ports:
- port: 5000
targetPort: 5000
nodePort: 30123 # Added
这将把服务端口5000绑定到主机的端口30123。如果您运行kubectl get svc
,这将为您提供稍微不同的输出。
kubernetes@kubernetes1:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d20h
private-registry-service ClusterIP 10.103.148.234 <none> 5000:30123/TCP 6h34m
注意映射30312:5000
。现在,您可以向该端口上的注册表发送一个请求:curl 192.168.1.138:30312
。您也可以省略nodePort
字段,然后kubernetes将为您选择一个在3000到32767之间的随机字段。它将显示在kubectl get svc
命令中,如上所示。Ingress
是不需要的,可以移除。
如果你想使用你提供的Ingress
,你需要使用一个入口控制器,比如nginx或traefik,也可以参阅kubernetes关于这个主题的文档。
[…]Ingress控制器负责实现Ingress,通常使用负载均衡器,但它也可能配置边缘路由器或其他前端来帮助处理流量。
编辑
有很多入口控制器,它们都有各自的优点和缺点。对于初学者来说,nginx可能是一个不错的选择,请参阅文档。
要安装它,请运行以下命令(从安装文档页面(
$ helm repo add nginx-stable https://helm.nginx.com/stable
$ helm repo update
$ helm install my-release nginx-stable/nginx-ingress
其中my-release
是一个随机名称,您可以任意选择。这将在您安装图表的名称空间中创建一个nginx pod。它还将创建一个类型为LoadBalancer
的nginx入口服务,如下所示:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP
my-release-nginx-ingress LoadBalancer 10.109.27.49 <pending> 80:30536/TCP,443:31694/TCP 111s
如您所见,EXTERNAL-IP
处于<pending>
状态。在像AWS这样的公共云环境中,会创建一个像ELB这样的负载均衡器资源,并且它的公共ip将作为EXTERNAL-IP
分配给服务。在您的内部部署设置中,它将保持在<pending>
状态。但是,正如您所看到的,两个随机节点端口被映射到http/https端口,就像上面的nodePort
设置一样。这里是80->30536和433->31694,对你来说,这将是类似的事情。
现在,您可以如上所述应用清单。您将获得ClusterIP
类型的服务。还创建一个Ingress
,如下所示:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: private-repository-service
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: private-repository-service
port:
number: 5000
现在,您可以针对主机curl -HHost:example.com "http://192.168.1.138:30536/"
运行curl(对我来说,它是30536端口,对您来说将是另一个端口(,您将从注册表中得到答案。与使用其他端口的https相同。
请注意,我在同一个命名空间中安装了所有内容。实际上,您应该有一个专用的入口命名空间。
我也强烈建议学习kubernetes的基础知识,例如通过Udemy课程或youtube教程系列。如果你想了解更多关于内部部署设置中的入口控制器的信息,请查看我关于该主题的另一个答案。
请在ingress.yaml中进行此更改,然后应用此入口。还请张贴kubectl get ingress
的输出
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-private-registry-service
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: kubernetes2
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: private-registry-service
port:
number: 5000
看起来您的私有存储库在default
命名空间中,而您正在test
命名空间中创建Service
和Ingress
。
我建议您将所有资源移动到同一个命名空间。如果出于某种原因,这是不可能的,那么您需要使用ServiceMesh范式,为此您可以找到一些工具,如Istio、Anthos等。