示例:Service连接应用程序
整体思路:
1.创建pod
2.创建关联上一步pod的service
3.使用不同的方式配置service从而能够在集群内部访问
4.使用ssl方式加密访问service
5.配置service为nodePort方式在外部进行访问
Kubernetes 的网络模型
通常,Docker 使用一种 host-private
的联网方式,在此情况下,只有两个容器都在同一个节点(主机)上时,一个容器才可以通过网络连接另一个容器。为了使 Docker 容器可以跨节点通信,必须在宿主节点(主机)的 IP 地址上分配端口,并将该端口接收到的网络请求转发(或代理)到容器中。这意味着,用户必须非常小心地为容器分配宿主节点(主机)的端口号,或者端口号可以自动分配。可以通俗的理解成不同主机的docker容器如何进行跨主机通信,具体可以参考这篇文章
在一个集群中,多个开发者之间协调分配端口号是非常困难的。Kubernetes 认为集群中的两个 Pod 应该能够互相通信,无论他们各自在哪个节点上。每一个 Pod 都被分配自己的 “cluster-private-IP”,因此,您无需在 Pod 间建立连接,或者将容器的端口映射到宿主机的端口。因此:
- Pod 中的任意容器可以使用 localhost 直连同 Pod 中另一个容器的端口
- 集群中的任意 Pod 可以使用另一的 Pod 的 cluster-private-IP 直连对方的端口,(无需 NAT 映射)
本文档的后续章节使用了一个 nginx server 的例子,详细阐述了如何使用这种网络模型发布 Service。
在集群中部署 Pod
部署 nginx 应用,并将关注点放在网络连接方面(请留意该 Pod 指定了一个 containerPort)。
- 创建文件
run-my-nginx.yaml
,文件内容如下
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
- 执行以下命令,部署 Pod 并检查运行情况:
kubectl apply -f ./run-my-nginx.yaml
kubectl get pods -l run=my-nginx -o wide
输出结果如下:
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd
- 执行命令
kubectl get pods -l run=my-nginx -o yaml | grep podIP
, 检查 Pod 的 IP 地址,输出结果如下:
podIP: 10.244.3.4
podIP: 10.244.2.5
在集群中的任意节点上,您可以执行 curl 10.244.3.4
或 curl 10.244.2.5
获得 nginx 的响应。此时:
- 容器并没有使用节点上的 80 端口
- 没有使用 NAT 规则对容器端口进行映射
这意味着,您可以
- 在同一节点上使用 80 端口运行多个 nginx Pod
- 在集群的任意节点/Pod 上使用 nginx Pod 的 clusterIP 访问 nginx 的 80 端口
同 Docker 一样,Kubernets 中,仍然可以将 Pod 的端口映射到宿主节点的网络地址上(使用 nodePort),但是使用 Kubernetes 的网络模型时,这类需求已经大大减少了。
为了区分两个不同的pod,可以登陆pod里的容器中,修改nginx的首页返回的信息,具体操作如下
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-5dc4865748-b69hc 1/1 Running 0 158m
my-nginx-5dc4865748-jkq45 1/1 Running 0 158m
[root@master ~]# kubectl exec my-nginx-5dc4865748-b69hc -i -t -- bash -il
root@my-nginx-5dc4865748-b69hc:/# cd /etc/nginx/conf.d/
root@my-nginx-5dc4865748-b69hc:/etc/nginx/conf.d# cat default.conf
......
root@my-nginx-5dc4865748-b69hc:/etc/nginx/conf.d# echo "1111" > /usr/share/nginx/html/index.html
root@my-nginx-5dc4865748-b69hc:/etc/nginx/conf.d# cat /usr/share/nginx/html/index.html
另一个pod中的容器nginx可以修改成返回2222.
创建 Service
上面的步骤中,我们已经创建了 nginx Pod,运行在集群的 IP 地址空间。您可以直接通过 Pod 的地址访问其端口,但是如果某一个 Pod 终止了该怎么办?Pod 因为故障或其他原因终止后,Deployment Controller 将创建一个新的 Pod 以替代该 Pod,但是 IP 地址将发生变化。Kubernetes Service 解决了这样的问题。
Kubernetes Service:
- 定义了集群中一组 Pod 的逻辑集合,该集合中的 Pod 提供了相同的功能
- 被创建后,获得一个唯一的 IP 地址(ClusterIP),直到该 Service 被删除,此地址不会发生改变
- Pod 可以直接连接 Service IP 地址上的端口,且发送到该 IP 地址的网络请求被自动负载均衡分发到 Service 所选取的 Pod 集合中
执行命令 kubectl expose deployment/my-nginx
可以为上面的两个 nginx Pod 创建 Service,输出结果如下所示:
service/my-nginx exposed
该命令等价于 kubectl apply -f nginx-svc.yaml
,其中 nginx-svc.yaml 文件的内容如下所示:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
run: my-nginx
该 yaml 文件将创建一个 Service:
- 该 Service 通过 label selector 选取包含
run: my-nginx
标签的 Pod 作为后端 Pod - 该 Service 暴露一个端口 80(
spec.ports[*].port
) - 该 Service 将 80 端口上接收到的网络请求转发到后端 Pod 的 80 (
spec.ports[*].targetPort
)端口上,支持负载均衡
执行命令 kubectl get svc my-nginx
,输出结果如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.0.162.149 <none> 80/TCP 21s
Service 的后端 Pod 实际上通过 Endpoints
来暴露。Kubernetes 会持续检查 Service 的 label selector spec.selector
,并将符合条件的 Pod 更新到与 Service 同名(my-nginx)的 Endpoints 对象。如果 Pod 终止了,该 Pod 将被自动从 Endpoints 中移除,新建的 Pod 将自动被添加到该 Endpoint。
执行命令 kubectl describe svc my-nginx
,输出结果如下,请注意 Endpoints 中的 IP 地址与上面获得的 Pod 地址相同:
Name: my-nginx
Namespace: default
Labels: run=my-nginx
Annotations: <none>
Selector: run=my-nginx
Type: ClusterIP
IP: 10.0.162.149
Port: <unset> 80/TCP
Endpoints: 10.244.2.5:80,10.244.3.4:80
Session Affinity: None
Events: <none>
执行命令 kubectl get ep my-nginx
,输出结果如下:
NAME ENDPOINTS AGE
my-nginx 10.244.2.5:80,10.244.3.4:80 1m
此时,您可以在集群的任意节点上执行 curl 10.0.162.149:80
,通过 Service 的 ClusterIP:Port 访问 nginx。
TIP Service 的 IP 地址是虚拟地址。请参考 虚拟 IP 的实现
访问 Service
Kubernetes 支持两种方式发现服务:
TIP
由于如下原因,您可能不想激活 Service 的环境变量发现机制:
- 可能与应用程序的环境变量冲突
- 太多的环境变量
- 只想使用 DNS 等
您可以在 Pod 的定义中,将 enableServiceLinks
标记设置为 false
环境变量
针对每一个有效的 Service,kubelet 在创建 Pod 时,向 Pod 添加一组环境变量。这种做法引发了一个 Pod 和 Service 的顺序问题。例如,
- 执行命令
kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
(您的 Pod 名字可能不一样),输出结果如下:
KUBERNETES_SERVICE_HOST=10.0.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
请注意,此时环境变量中没有任何与您的 Service 相关的内容。因为在本教程的前面部分,我们先创建了 Pod 的副本,后创建了 Service。如果我们删除已有的两个 Pod,Deployment 将重新创建 Pod 以替代被删除的 Pod。此时,因为在创建 Pod 时,Service 已经存在,所以我们可以在新的 Pod 中查看到 Service 的环境变量被正确设置。
执行命令 kubectl delete pods -l run=my-nginx
以删除 Pod
执行命令 kubectl get pods -l run=my-nginx -o wide
查看新建Pod,输出结果如下:
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-e9ihh 1/1 Running 0 5s 10.244.2.7 kubernetes-minion-ljyd
my-nginx-3800858182-j4rm4 1/1 Running 0 5s 10.244.3.8 kubernetes-minion-905m
执行命令 kubectl exec my-nginx-3800858182-e9ihh -- printenv | grep SERVICE
(Pod 重建后,名字将会发生变化。请使用您的 Pod 名),输出结果如下,Service 相关的环境变量已经被正确设置
KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.0.162.149
KUBERNETES_SERVICE_HOST=10.0.0.1
MY_NGINX_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
DNS
Kubernetes 提供了一个 DNS cluster addon,可自动为 Service 分配 DNS name。前提条件是已经安装coredns
执行命令 kubectl get services kube-dns --namespace=kube-system
查看该 addon 在您的集群上是否可用,输出结果如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.0.0.10 <none> 53/UDP,53/TCP 8m
本章节假设:
- 您已经按照本文前面的章节创建了 Service(my-nginx)
- 您已经安装了 DNS Server(CoreDNS cluster addon)
此时,您可以从集群中任何 Pod 中按 Service 的名称访问该 Service。
- 执行命令
kubectl run curl --image=radial/busyboxplus:curl -i --tty
获得 busyboxplus 容器的命令行终端,该命令输出结果如下所示:
Waiting for pod default/curl-131556218-9fnch to be running, status is Pending, pod ready: false
Hit enter for command prompt
然后,单击回车键,并执行命令 nslookup my-nginx
,输出结果如下所示:
[ root@curl-131556218-9fnch:/ ]$ nslookup my-nginx
Server: 10.0.0.10
Address 1: 10.0.0.10
Name: my-nginx
Address 1: 10.0.162.149
- 执行命令
curl my-nginx:80
,可获得 Nginx 的响应。 - 执行命令
exit
可推出该容器的命令行 - 执行命令
kubectl delete deployment curl
可删除刚才创建的curl
测试容器
注意:使用上述命令删除curl测试容器的话会报错,具体如下:
# kubectl delete deployment curl
Error from server (NotFound): deployments.apps "curl" not found
通过查看可知这只是一个单独的pod,并没有采用deployment的方式部署,所以,删除的话使用如下命令
[root@master ~]# kubectl delete deployments.apps curl-deployment
deployment.apps "curl-deployment" deleted
[root@master ~]# kubectl delete pods curl-deployment-76c66b6b4b-bgcbs
pod "curl-deployment-76c66b6b4b-bgcbs" deleted
保护 Service 的安全
到目前为止,我们只是从集群内部访问了 nginx server。在将该 Service 公布到互联网时,您可能需要确保该通信渠道是安全的。为此,您必须:
- 准备 https 证书(购买,或者自签名)
- 将该 nginx 服务配置好,并使用该 https 证书
- 配置 Secret,以使得其他 Pod 可以使用该证书
您可按照如下步骤配置 nginx 使用自签名证书:
- 创建密钥对
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt -subj "/CN=my-nginx/O=my-nginx"
将密钥对转换为 base64 编码
cat /tmp/nginx.crt | base64
cat /tmp/nginx.key | base64
创建一个如下格式的 nginxsecrets.yaml 文件,使用前面命令输出的 base64 编码替换其中的内容(base64编码内容不能换行)(请使用前面两行命令生成的结果替换 nginx.crt 和 nginx.key 的内容,)
apiVersion: "v1"
kind: "Secret"
metadata:
name: "nginxsecret"
namespace: "default"
data:
nginx.crt: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIekNDQWdlZ0F3SUJBZ0lKQUp5M3lQK0pzMlpJTUEwR0NTcUdTSWIzRFFFQkJRVUFNQ1l4RVRBUEJnTlYKQkFNVENHNW5hVzU0YzNaak1SRXdEd1lEVlFRS0V3aHVaMmx1ZUhOMll6QWVGdzB4TnpFd01qWXdOekEzTVRKYQpGdzB4T0RFd01qWXdOekEzTVRKYU1DWXhFVEFQQmdOVkJBTVRDRzVuYVc1NGMzWmpNUkV3RHdZRFZRUUtFd2h1CloybHVlSE4yWXpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBSjFxSU1SOVdWM0IKMlZIQlRMRmtobDRONXljMEJxYUhIQktMSnJMcy8vdzZhU3hRS29GbHlJSU94NGUrMlN5ajBFcndCLzlYTnBwbQppeW1CL3JkRldkOXg5UWhBQUxCZkVaTmNiV3NsTVFVcnhBZW50VWt1dk1vLzgvMHRpbGhjc3paenJEYVJ4NEo5Ci82UVRtVVI3a0ZTWUpOWTVQZkR3cGc3dlVvaDZmZ1Voam92VG42eHNVR0M2QURVODBpNXFlZWhNeVI1N2lmU2YKNHZpaXdIY3hnL3lZR1JBRS9mRTRqakxCdmdONjc2SU90S01rZXV3R0ljNDFhd05tNnNTSzRqYUNGeGpYSnZaZQp2by9kTlEybHhHWCtKT2l3SEhXbXNhdGp4WTRaNVk3R1ZoK0QrWnYvcW1mMFgvbVY0Rmo1NzV3ajFMWVBocWtsCmdhSXZYRyt4U1FVQ0F3RUFBYU5RTUU0d0hRWURWUjBPQkJZRUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjcKTUI4R0ExVWRJd1FZTUJhQUZPNG9OWkI3YXc1OUlsYkROMzhIYkduYnhFVjdNQXdHQTFVZEV3UUZNQU1CQWY4dwpEUVlKS29aSWh2Y05BUUVGQlFBRGdnRUJBRVhTMW9FU0lFaXdyMDhWcVA0K2NwTHI3TW5FMTducDBvMm14alFvCjRGb0RvRjdRZnZqeE04Tzd2TjB0clcxb2pGSW0vWDE4ZnZaL3k4ZzVaWG40Vm8zc3hKVmRBcStNZC9jTStzUGEKNmJjTkNUekZqeFpUV0UrKzE5NS9zb2dmOUZ3VDVDK3U2Q3B5N0M3MTZvUXRUakViV05VdEt4cXI0Nk1OZWNCMApwRFhWZmdWQTRadkR4NFo3S2RiZDY5eXM3OVFHYmg5ZW1PZ05NZFlsSUswSGt0ejF5WU4vbVpmK3FqTkJqbWZjCkNnMnlwbGQ0Wi8rUUNQZjl3SkoybFIrY2FnT0R4elBWcGxNSEcybzgvTHFDdnh6elZPUDUxeXdLZEtxaUMwSVEKQ0I5T2wwWW5scE9UNEh1b2hSUzBPOStlMm9KdFZsNUIyczRpbDlhZ3RTVXFxUlU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
nginx.key: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2RhaURFZlZsZHdkbFIKd1V5eFpJWmVEZWNuTkFhbWh4d1NpeWF5N1AvOE9ta3NVQ3FCWmNpQ0RzZUh2dGtzbzlCSzhBZi9WemFhWm9zcApnZjYzUlZuZmNmVUlRQUN3WHhHVFhHMXJKVEVGSzhRSHA3VkpMcnpLUC9QOUxZcFlYTE0yYzZ3MmtjZUNmZitrCkU1bEVlNUJVbUNUV09UM3c4S1lPNzFLSWVuNEZJWTZMMDUrc2JGQmd1Z0ExUE5JdWFubm9UTWtlZTRuMG4rTDQKb3NCM01ZUDhtQmtRQlAzeE9JNHl3YjREZXUraURyU2pKSHJzQmlIT05Xc0RadXJFaXVJMmdoY1kxeWIyWHI2UAozVFVOcGNSbC9pVG9zQngxcHJHclk4V09HZVdPeGxZZmcvbWIvNnBuOUYvNWxlQlkrZStjSTlTMkQ0YXBKWUdpCkwxeHZzVWtGQWdNQkFBRUNnZ0VBZFhCK0xkbk8ySElOTGo5bWRsb25IUGlHWWVzZ294RGQwci9hQ1Zkank4dlEKTjIwL3FQWkUxek1yall6Ry9kVGhTMmMwc0QxaTBXSjdwR1lGb0xtdXlWTjltY0FXUTM5SjM0VHZaU2FFSWZWNgo5TE1jUHhNTmFsNjRLMFRVbUFQZytGam9QSFlhUUxLOERLOUtnNXNrSE5pOWNzMlY5ckd6VWlVZWtBL0RBUlBTClI3L2ZjUFBacDRuRWVBZmI3WTk1R1llb1p5V21SU3VKdlNyblBESGtUdW1vVlVWdkxMRHRzaG9reUxiTWVtN3oKMmJzVmpwSW1GTHJqbGtmQXlpNHg0WjJrV3YyMFRrdWtsZU1jaVlMbjk4QWxiRi9DSmRLM3QraTRoMTVlR2ZQegpoTnh3bk9QdlVTaDR2Q0o3c2Q5TmtEUGJvS2JneVVHOXBYamZhRGR2UVFLQmdRRFFLM01nUkhkQ1pKNVFqZWFKClFGdXF4cHdnNzhZTjQyL1NwenlUYmtGcVFoQWtyczJxWGx1MDZBRzhrZzIzQkswaHkzaE9zSGgxcXRVK3NHZVAKOWRERHBsUWV0ODZsY2FlR3hoc0V0L1R6cEdtNGFKSm5oNzVVaTVGZk9QTDhPTm1FZ3MxMVRhUldhNzZxelRyMgphRlpjQ2pWV1g0YnRSTHVwSkgrMjZnY0FhUUtCZ1FEQmxVSUUzTnNVOFBBZEYvL25sQVB5VWs1T3lDdWc3dmVyClUycXlrdXFzYnBkSi9hODViT1JhM05IVmpVM25uRGpHVHBWaE9JeXg5TEFrc2RwZEFjVmxvcG9HODhXYk9lMTAKMUdqbnkySmdDK3JVWUZiRGtpUGx1K09IYnRnOXFYcGJMSHBzUVpsMGhucDBYSFNYVm9CMUliQndnMGEyOFVadApCbFBtWmc2d1BRS0JnRHVIUVV2SDZHYTNDVUsxNFdmOFhIcFFnMU16M2VvWTBPQm5iSDRvZUZKZmcraEppSXlnCm9RN3hqWldVR3BIc3AyblRtcHErQWlSNzdyRVhsdlhtOElVU2FsbkNiRGlKY01Pc29RdFBZNS9NczJMRm5LQTQKaENmL0pWb2FtZm1nZEN0ZGtFMXNINE9MR2lJVHdEbTRpb0dWZGIwMllnbzFyb2htNUpLMUI3MkpBb0dBUW01UQpHNDhXOTVhL0w1eSt5dCsyZ3YvUHM2VnBvMjZlTzRNQ3lJazJVem9ZWE9IYnNkODJkaC8xT2sybGdHZlI2K3VuCnc1YytZUXRSTHlhQmd3MUtpbGhFZDBKTWU3cGpUSVpnQWJ0LzVPbnlDak9OVXN2aDJjS2lrQ1Z2dTZsZlBjNkQKckliT2ZIaHhxV0RZK2Q1TGN1YSt2NzJ0RkxhenJsSlBsRzlOZHhrQ2dZRUF5elIzT3UyMDNRVVV6bUlCRkwzZAp4Wm5XZ0JLSEo3TnNxcGFWb2RjL0d5aGVycjFDZzE2MmJaSjJDV2RsZkI0VEdtUjZZdmxTZEFOOFRwUWhFbUtKCnFBLzVzdHdxNWd0WGVLOVJmMWxXK29xNThRNTBxMmk1NVdUTThoSDZhTjlaMTltZ0FGdE5VdGNqQUx2dFYxdEYKWSs4WFJkSHJaRnBIWll2NWkwVW1VbGc9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
使用该文件创建 Secrets
# 创建 Secrets
kubectl apply -f nginxsecrets.yaml
# 查看 Secrets
kubectl get secrets
输出结果为:
NAME TYPE DATA AGE
default-token-il9rc kubernetes.io/service-account-token 1 1d
nginxsecret Opaque 2 1m
修改 nginx 部署,使 nginx 使用 Secrets 中的 https 证书,修改 Service,使其暴露 80 端口和 443端口。nginx-secure-app.yaml 文件如下所示:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
containers:
- name: nginxhttps
image: bprashanth/nginxhttps:1.0
ports:
- containerPort: 443
- containerPort: 80
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
关于 nginx-secure-app.yaml
- 该文件同时包含了 Deployment 和 Service 的定义
- nginx server 监听 HTTP 80 端口和 HTTPS 443 端口的请求, nginx Service 同时暴露了这两个端口
- nginx 容器可以通过
/etc/nginx/ssl
访问到 https 证书,https 证书存放在 Secrets 中,且必须在 Pod 创建之前配置好。
执行命令使该文件生效:
kubectl delete deployments,svc my-nginx
kubectl create -f ./nginx-secure-app.yaml
此时,您可以从任何节点访问该 nginx server
kubectl get pods -o yaml | grep -i podip
podIP: 10.244.3.5
node $ curl -k https://10.244.3.5
...
<h1>Welcome to nginx!</h1>
curl -k
- 在 curl 命令中指定 —k 参数,是因为我们在生成 https 证书时,并不知道 Pod 的 IP 地址,因此,在执行 curl 命令时必须忽略 CName 不匹配的错误。
- 通过创建 Service,我们将 https 证书的 CName 和 Service 的实际 DNS Name 联系起来,因此,我们可以尝试在另一个 Pod 中使用 https 证书的公钥访问 nginx Service。此时,curl 指令不在需要 -k 参数
创建 curlpod.yaml 文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: curl-deployment
spec:
selector:
matchLabels:
app: curlpod
replicas: 1
template:
metadata:
labels:
app: curlpod
spec:
volumes:
- name: secret-volume
secret:
secretName: nginxsecret
containers:
- name: curlpod
command:
- sh
- -c
- while true; do sleep 1; done
image: radial/busyboxplus:curl
volumeMounts:
- mountPath: /etc/nginx/ssl
name: secret-volume
执行命令,完成 curlpod 的部署
kubectl apply -f ./curlpod.yaml
kubectl get pods -l app=curlpod
输出结果如下:
NAME READY STATUS RESTARTS AGE
curl-deployment-1515033274-1410r 1/1 Running 0 1m
执行 curl,访问 nginx 的 https 端口(请使用您自己的 Pod 名称)
kubectl exec curl-deployment-1515033274-1410r -- curl https://my-nginx --cacert /etc/nginx/ssl/nginx.crt
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 12 100 12 0 0 99 0 --:--:-- --:--:-- --:--:-- 203
...
<title>Welcome to nginx!</title>
...
暴露 Service
在您的应用程序中,可能有一部分功能需要通过 Service 发布到一个外部的 IP 地址上。Kubernetes 支持如下两种方式:
- NodePort
- LoadBalancer
- 需要云环境支持,本文不做过多阐述,如需了解,请参考 Exposing the Service
在上一个章节 保护 Service 的安全 中创建的 Service 已经是 NodePort 类型的了,此时,如果您的节点有公网地址,则 nginx HTTPS 部署已经可以接受来自于互联网的请求了。
假若上一步的"保护 Service 的安全"没有进行操作,可以直接修改该servie中的yaml文件,修改ClusterIP为nodePort,从而继续进行下面的步骤
执行命令 kubectl get svc my-nginx -o yaml | grep nodePort -C 5
,输出结果如下:
结果中的
nodePort
将被标记为红色字体
spec:
clusterIP: 10.0.162.149
ports:
- name: http
nodePort: 31704
port: 8080
protocol: TCP
targetPort: 80
- name: https
nodePort: 32453
port: 443
protocol: TCP
targetPort: 443
selector:
run: my-nginx
假设您的某一节点的公网 IP 地址为 23.251.152.56,则您可以使用任意一台可上网的机器执行命令 curl https://23.251.152.56:32453 -k
。输出结果为:
...
<h1>Welcome to nginx!</h1>
Ingress
- 对于 HTTP、HTTPS 形式的访问推荐使用 Ingress 替代这种用法,参考 Ingress通过互联网访问您的应用
- 对于 TCP、UDP 等形式的访问,您仍然应该使用 Service NodePort
示例:Service连接应用程序的更多相关文章
- 改善Azure App Service托管应用程序性能的几个技巧
本文介绍了几个技巧,这些技巧可以改善Azure App Service托管应用程序的性能.其中一些技巧是你现在就可以进行的配置变更, 而其他技巧则可能需要对应用程序进行一些重新设计和重构. 开发者都希 ...
- 分布式 PostgreSQL 集群(Citus)官方示例 - 多租户应用程序实战
如果您正在构建软件即服务 (SaaS) 应用程序,您可能已经在数据模型中内置了租赁的概念. 通常,大多数信息与租户/客户/帐户相关,并且数据库表捕获这种自然关系. 对于 SaaS 应用程序,每个租户的 ...
- 用JQuery中的Ajax方法获取web service等后台程序中的方法
用JQuery中的Ajax方法获取web service等后台程序中的方法 1.准备需要被前台html页面调用的web Service,这里我们就用ws来代替了,代码如下: using System; ...
- MFC通过ODBC连接Mysql程序
分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 MFC通过ODBC连接 ...
- C#之VS2010ASP.NET页面调用Web Service和winform程序调用Web Service
一:用ASP.NET调用Web Service 打开VS2010,打开“文件-新建-网站”,选择“ASP.NET网站” 选好存储位置,语言后点击确定,进入默认页面.然后先添加Web引用,把WebSer ...
- 示例的libevent的程序
著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:auxten 链接:http://zhuanlan.zhihu.com/auxten/20315482 来源:知乎 /* ...
- 课程作业01:模仿JavaAppArguments.java示例,编写一个程序,此程序从命令行接收多个数字,求和之后输出结果。
1.设计思想: 首先是从JavaAppArguments.java示例开始,此示例已打印参数,定义数字 之和和作为存储单位的整型,然后将输入参数的字符串转化为整型,之后求和即可. 2.程序流程图: 3 ...
- JAVA本地远程连接linux程序监控状态
环境: 1.本地window 2.程序部署在centos 一,启动访问权限安全守护程序 新建文件:jstatd.all.policy ,注意路径 grant codebase "$JA ...
- android中service启动后台程序
Service是Android中一个类,它是Android四大组件之一,使用Service可以在后台执行长时间的操作( perform long-running operations in the b ...
随机推荐
- Centos7借助docker部署mysql,提供远程链接服务
Centos7 借助docker部署mysql,并提供远程连接服务 安装docker 运行docker 注意安装docker和运行docker的步骤很简单,可以参考我学习docker的笔记 docke ...
- Centos7中配置NIS:用户账号管理
NIS:网络信息服务 Linux系统中用户按地域分两类:本地用户,远程用户(NIS.LDAP.AD)模式:C/S模式 ypbind是定义NIS服务器的客户端进程,一旦确定了服务器位置,客户端绑定到了服 ...
- 常用的函数式接口_Supplier和常用的函数式接口Supplier接口练习_求数组中元素最大值
Supplier接口 package com.yang.Test.SupplierStudy; import java.util.function.Supplier; /** * 常用的函数式接口 * ...
- 浅谈 Lucas 定理
Lucas 定理是用来求 \(C^n_m\bmod p\) 的. 定理 \[C^n_m\equiv C^{n\bmod p}_{m\bmod p}\cdot C^{\lfloor n/p\rfloor ...
- 举重若轻流水行云,前端纯CSS3实现质感非凡的图片Logo鼠标悬停(hover)光泽一闪而过的光影特效
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_197 喜欢看电影的朋友肯定会注意到一个有趣的细节,就是电影出品方一定会在片头的Logo环节做一个小特效:暗影流动之间光泽一闪而过, ...
- 在win10系统环境下,安装配置sublime 3,构建python和vue.js开发环境(插件)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_131 疫情当下,最近一直在用mac下的虚拟机运行win10系统,由于在线人数过多,直播授课的时候使用vscode的时候内存暴涨,于 ...
- mosquitto使用的基本流程以及一些遇见的问题
改配置文件 以记事本的方式打开mosquitto.conf更改部分内容,找到# listener port-number [ip address/host name/unix socket path] ...
- Spring源码 19 IOC getBean
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 08 IOC refresh方法3
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- fast json 乱序问题解决过程
解决问题:保存到redis中的jsonstring在转回jsonObject的时候乱序: 解决方案:https://inlhx.iteye.com/blog/2312512 解决过程: 1 看fast ...