はじめに
Oracle Cloud上でKubernetesクラスタを構成するサービスOKE上で、Nginx Ingress Controllerを使用し、
Ingressを介してKubernetesのクラスタ内のサービスへアクセスできるようになるまでにした事を書きます。
前提条件
ローカル環境でOKEへkubectlによりアクセスできる状態である事が前提です。
OKEの始め方のチュートリアルや記事については以下が参考になります。
Nginx Ingress Controllerの設定
nginxinc/kubernetes-ingressのinstallation.mdに従って作業を進めました。
用意
nginxinc/kubernetes-ingressをgithubよりcloneします。
このレポジトリのdeployment以下のファイルを使用しました。
$ git clone https://github.com/nginxinc/kubernetes-ingress
$ cd kubernetes-ingress/deployments
Nginx Ingress Controllerのデプロイ作業
- Kubernetes上にNginx Ingress Controller用のNamespaceとServiceAccountを追加します。
$ kubectl apply -f common/ns-and-sa.yaml
common/ns-and-sa.yamlの中身は以下のようになっています。
apiVersion: v1
kind: Namespace
metadata:
name: nginx-ingress
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress
namespace: nginx-ingress
2. Kubernetes上にtls用のSecretを作成します。
$ kubectl apply -f common/default-server-secret.yaml
common/default-server-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: default-server-secret
namespace: nginx-ingress
type: Opaque
data:
tls.crt: ???
tls.key: ???
KubernetesのSecretについては以下のURLが参考になります。
https://kubernetes.io/docs/concepts/configuration/secret/
3. Kubernetes上にNginx Ingress Controller用のConfigMapを作成します。
$ kubectl apply -f common/nginx-config.yaml
common/nginx-config.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:
dataセクションに書ける内容については、以下のURLを参照してください。
https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/configmap-and-annotations.md
4. RBACの設定を行います。
ここでは、適切な権限を持ったOracle Cloud InfrastructureのユーザとKubernetes上のClusterRoleBindingを紐付ける必要があるようです。
UserはPolicyで以下の権限を持たせたgroupに割り当てられているものを使用しました。
allow group <group名> to manage cluster-family in tenancy
allow group <group名> to inspect vcns in tenancy
allow group <group名> to inspect subnets in tenancy
実行するコマンドは以下の様になります。
kubectl create clusterrolebinding nginx-ingress --clusterrole=cluster-admin --user=<user OCID> --serviceaccount=nginx-ingress:nginx-ingress
参考ドキュメント:
https://docs.cloud.oracle.com/iaas/Content/ContEng/Concepts/contengaboutaccesscontrol.htm
5. ClusterRoleを追加します。
以下のファイルを作成します。
clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: nginx-ingress
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- update
- create
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- list
- watch
- get
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update
次のコマンドを実行します。
$ kubectl apply -f clusterrole.yaml
6. Kubernetes上にNginx Ingress Controllerをデプロイします。
$ kubectl apply -f deployment/nginx-ingress.yaml
deployment/nginx-ingress.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
spec:
serviceAccountName: nginx-ingress
containers:
- image: nginx/nginx-ingress:edge
imagePullPolicy: Always
name: nginx-ingress
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
#- -v=3 # Enables extensive logging. Useful for trooublshooting.
#- -report-ingress-status
#- -external-service=nginx-ingress
#- -enable-leader-election
7. デプロイができたかを確認します。
以下のコマンドを実行してPodの状態がRunningならば大丈夫です。
$ kubectl get pods --namespace=nginx-ingress
8. 次のコマンドを実行します。
$ kubectl apply -f service/loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
externalTrafficPolicy: Local
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
selector:
app: nginx-ingress
この時点で、Oracle Cloud Infrastructure上にPublic IPが自動的に取得されるようです。
$ kubectl get service -n nginx-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress LoadBalancer 10.96.6.156 <Public IP> 80:30024/TCP,443:32241/TCP 4h
以上でNginx Ingress Controllerのデプロイができました。
サービスのデプロイ
実際にIngressとサービスをデプロイする手順です。
1. 例として次のファイルでサービスをデプロイします。
hello.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: hello-k8s-deployment
spec:
selector:
matchLabels:
app: helloworld
replicas: 1
template:
metadata:
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: karthequian/helloworld:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: hello-k8s-service
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: helloworld
$ kubectl apply -f hello.yaml
2. 次のファイルを使用してIngressを作り、hello-k8s-serviceと紐付けます。
ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: helloworld-ingress
spec:
rules:
- host: hello.example.com
http:
paths:
- path: /
backend:
serviceName: hello-k8s-service
servicePort: 80
$ kubectl apply -f ingress.yaml
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
helloworld-ingress hello.example.com 80 3h
この時点で、LoadBalancer作成じに取得されたOracle Cloud InfrastructureのPublic IPに
hello.example.comのドメイン名でアクセスすれば、HelloWorldのPodの動作を確認できます。
curlコマンドでの確認
$ curl --resolve hello.example.com:80:<Public IP> http://hello.example.com
<html>
......
</html>
ブラウザからの確認
まずhello.example.comとPublic IPを紐付けるDNSサーバを用意して、
そこを参照するようにしてください。
macOSの場合はここを参考にしてdnsmasqを設定できました。
dnsmasqを設定したら、システム環境設定->ネットワーク->詳細->DNSで、
参照するDNSサーバの表の一番上に127.0.0.1を指定してください。
DNSサーバの設定ができれば、ブラウザからPublic IPにアクセスしてページを見る事ができます。
今回は以上です。